使用 mysql 中的间隔在数据库日期中添加月份

Add months in db date using interval in mysql

我想通过加入计划 table 和交易 table 使用 mysql 间隔函数在交易日期中添加月份,但是这种方法不起作用但是如果我以静态方式添加月份到交易日期它正在工作。

plan table:

plan_id    plan
1         6 month    
2         12 month    
3         3 month

transaction table:

id  user_id  subscribed_on   plan_id    
1     2       2020-04-04     1    
2     4       2019-02-22     2 

Mysql 查询(无效):

SELECT t.* FROM transaction t inner join plan p on p.plan_id=t.plan_id 
where t.user_id=2 and DATE_ADD(date(t.subscribed_on), INTERVAL p.plan) >= CURDATE() 
order by t.id desc

如果我以静态方式添加月份而不是工作正常:

SELECT t.* FROM transaction t inner join plan p on p.plan_id=t.plan_id 
where t.user_id=2 and DATE_ADD(date(t.subscribed_on),
INTERVAL 6 month) >= CURDATE() 
order by t.id desc

很遗憾,数据中的字符串不等同于区间。一种方法是:

date(t.subscribed_on) + interval substring_index(plan, ' ') + 0 month

这里注意month是关键字,不是字符串

MySQL 不支持这样使用间隔。与其他数据库(例如 Postgres)不同,单位参数是关键字,而不是文字字符串。

我怀疑您的 table 可能会存储其他时间间隔,而不仅仅是几个月(例如,年、天等)。如果是这样,您可以使用字符串函数和 case 表达式来适应不同的可能值,例如:

select t.* 
from transaction t 
inner join plan p on p.plan_id = t.plan_id 
where 
    t.user_id = 2 
    and date(t.subscribed_on) + case substring_index(p.plan, ' ', -1)
        when 'year'  then interval substring_index(p.plan, ' ', 1) year
        when 'month' then interval substring_index(p.plan, ' ', 1) month
        when 'day'   then interval substring_index(p.plan, ' ', 1) day
    end
    >= current_date
order by t.id desc

这里的逻辑是将存储的区间字符串拆分为两部分:数字,和单位; case 表达式处理单位并相应地生成适当的文字间隔。

尝试强制 plan table 中的 plan 列为整数。似乎无法将字符串转换为间隔。

我这样试过:

WITH
plan( plan_id,plan) AS (
          SELECT 1,'6 month'
UNION ALL SELECT 2,'12 month'    
UNION ALL SELECT 3,'3 month'
)
,
transaction(id,user_id,subscribed_on,plan_id) AS (
          SELECT 1,2,DATE '2020-09-04',1    
UNION ALL SELECT 2,4,DATE '2019-02-22',2 
)
SELECT t.*
FROM transaction t
INNER JOIN plan p ON p.plan_id = t.plan_id
WHERE t.user_id = 2
  AND DATE_ADD(
        DATE(t.subscribed_on)
      , INTERVAL CAST(REPLACE(plan,' month','') AS SIGNED) MONTH
    ) >= CURDATE()
ORDER BY t.id DESC

(returns 没有结果,因为您的示例数据中没有任何足够高的日期...)