【问题标题】:Mysql Generate each date from date range listMysql从日期范围列表中生成每个日期
【发布时间】:2016-04-18 20:58:30
【问题描述】:

我有一个查询(从 bla.. bla.. 中选择 *)产生这样的日期范围结果:

code | date1 | date2

a | 2016-04-19  | 2016-04-21 |

b | 2016-04-13  | 2016-04-14 |

我想在 date1 和 date2 之间生成该日期范围的每一天,如下所示:

代码 |日期结果

a | 2016-04-19

a | 2016-04-20

a | 2016-04-21

b | 2016-04-13

b | 2016-04-14

我找到了在两个日期范围之间产生每个日期的查询示例,如下所示:

SELECT ADDDATE('2016-04-10', INTERVAL @i:=@i+1 DAY) AS DAY
FROM (
SELECT a.a
FROM (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
CROSS JOIN (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
) a
JOIN (SELECT @i := -1) r1
WHERE 
@i < DATEDIFF('2016-04-19', '2016-04-10')

但我无法用我的查询来实现它:(

【问题讨论】:

    标签: mysql date


    【解决方案1】:

    您可以使用 from_days() 将日期转换为天数 然后使用计数表进行内部连接(序号从 1 开始) 数字 730485 是 '2000-01-01' 偏移量(select from_days('2000-01-01'))

    select a.* , from_days(t.tallyid+730485) from 
    (
        select 'a' code , '2016-04-19' date1,  '2016-04-21' date2
        union all
        select 'b'code , '2016-04-13' date1,  '2016-04-14' date2
    ) a
    inner join Tally t on t.tallyid between (TO_DAYS(a.date1)-730485) and (TO_DAYS(a.date2)-730485)
    

    【讨论】:

    • 很有趣.. 但很抱歉,如果我不想创建像计数表这样的临时表,我怎样才能让它在单个查询中工作?
    【解决方案2】:

    这里是单个查询:

    select a.* , from_days(t.tallyid+730485) from 
    (
        select 'a' code , '2016-04-19' date1,  '2016-04-21' date2
        union all
        select 'b'code , '2016-04-13' date1,  '2016-04-14' date2,
    ) a
    left join 
    (
        SELECT @row := @row + 1 as tallyid FROM 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t5, 
        (SELECT @row:=0) a
    ) t on t.tallyid between (TO_DAYS(a.date1)-730485) and (TO_DAYS(a.date2)-730485)
    

    从 1 到 100000 的序列是在子查询中创建的,它适用于 2000 年到 2237 年之间的日期。

    【讨论】:

      【解决方案3】:

      最后我找到了生成从 date1 到 date2 的日期的答案:

      select 
      *
      from (
          select t.*, t.date1 + INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as tanggal
          from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
          cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
          cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
          join (
              select date1,date2 from mytable
          ) t
          where t.date1 + INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY <= t.date2
      ) a
      

      谢谢你们的赞赏

      【讨论】:

        猜你喜欢
        • 2019-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        相关资源
        最近更新 更多