【问题标题】:Add months in db date using interval in mysql使用 mysql 中的间隔在数据库日期中添加月份
【发布时间】:2020-10-10 13:16:24
【问题描述】:

我想通过加入计划表和事务表使用mysql间隔函数在事务日期中添加月份,但是这种方法不起作用但是如果我以静态方式将月份添加到事务日期它是有效的。

plan表:

plan_id    plan
1         6 month    
2         12 month    
3         3 month

transaction表:

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

【问题讨论】:

    标签: mysql sql datetime intervals


    【解决方案1】:

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

    我怀疑您的表可能会存储其他时间间隔,而不仅仅是几个月(例如,年、日等)。如果是这样,您可以使用字符串函数和 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 表达式处理该单元并相应地生成适当的文字间隔。

    【讨论】:

    • 这里您提到手动编写案例月年日我加入计划表可以是月或年,您可以通过加入查询告诉我。
    • @msp:是的。这就是我回答中的查询所做的。
    • 我无法理解 bcoz 该怎么做,年月日正在以静态方式传递,我将如何工作?
    • @msp:case 表达式查看表内的内容,并相应地生成正确的间隔。试试这个查询!
    【解决方案2】:

    不幸的是,数据中的字符串不等于间隔。一种方法是:

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

    注意这里month是一个关键字,而不是一个字符串。

    【讨论】:

    • 我不能用 6 个月或 12 个月吗?
    • @msp 。 . .这将从plan 列中提取数字。我不确定你在问什么。
    【解决方案3】:

    尝试将plan 表中的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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多