我有一个用于存储事件数据的表,其中包含以下两个条目
id | title | startdate | enddate
1 | event1 | 2019-04-01 | 2019-04-04
2 | event2 | 2019-04-04 | 2019-04-05
我需要编写一个查询以将数据提取为
id| title | date
1 | event1 | 2019-04-01
1 | event1 | 2019-04-02
1 | event1 | 2019-04-03
1 | event1 | 2019-04-04
1 | event2 | 2019-04-04
1 | event2 | 2019-04-05
请提出任何查询。
请查询MySQL。
答案 0 :(得分:1)
解决方案可以通过创建一个表格来解决,该表格的日期大约为273年。 下面的查询创建表:
CREATE TABLE test2 AS
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9);
CREATE TABLE calendar AS
select adddate('1900-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) sdate
from test2 t0,test2 t1,test2 t2,test2 t3,test2 t4;
您可以更改和增加的日历表范围:
MIN(sdate) MAX(sdate) 1900-01-01 2173-10-15
使用上面的表格,您可以生成所需范围之间的日期。下面的查询提供您的解决方案:
SELECT id,title,c.sdate as "date"
FROM test t
INNER JOIN calendar c
ON c.sdate BETWEEN t.startdate AND t.enddate;
输出:
id title date
1 event1 2019-04-01
1 event1 2019-04-02
1 event1 2019-04-03
1 event1 2019-04-04
2 event2 2019-04-04
2 event2 2019-04-05
有关演示,请点击以下链接:
答案 1 :(得分:0)
您可以将两列合并为一..没有这样的方法。
SELECT id,title,concat(startdate ,", ",enddate) as date FROM `table`
结果应该是
id| title | date
1 | event2 | 2019-04-04, 2019-04-05
2 | event1 | 2019-04-01, 2019-04-02
现在您可以使用php或其他语言将“日期”分成两个字符串/列。.
答案 2 :(得分:0)
您可以不创建表而进行操作。以下查询用于在不创建或引用任何表的情况下创建日期范围:
SELECT 1 as 'tempid',CONCAT_WS('-','2019-04',LPAD((a+b),2,0)) AS 'dates'
FROM
(SELECT 0 a UNION
SELECT 1 UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5 UNION
SELECT 6 UNION
SELECT 7 UNION
SELECT 8 UNION
SELECT 9) a,
(SELECT 0 b UNION
SELECT 10 UNION
SELECT 20 UNION
SELECT 30) dd;
请注意,如果您运行上面的查询,您将获得介于2019-04-00和2019-04-39之间的日期范围。
SELECT t.id,t.title,d.dates FROM
(SELECT 1 as 'tempid',CONCAT_WS('-','2019-04',LPAD((a+b),2,0)) AS 'dates'
FROM
(SELECT 0 a UNION
SELECT 1 UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5 UNION
SELECT 6 UNION
SELECT 7 UNION
SELECT 8 UNION
SELECT 9) a,
(SELECT 0 b UNION
SELECT 10 UNION
SELECT 20 UNION
SELECT 30) d) d LEFT JOIN
-- this part here is your query from the table
(SELECT id,title,startdate,enddate,1 AS tempid
FROM your_table) t
ON d.tempid=t.tempid WHERE d.dates BETWEEN startdate AND enddate;
编辑:如果您希望整年不创建表格,则可以使用以下查询:
SELECT CONCAT_WS('-',yy,LPAD(m,2,0),LPAD(days,2,0)) dates FROM
(SELECT 1 AS id,a+b AS 'days' FROM
(SELECT 0 a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9) a,
(SELECT 0 b UNION SELECT 10 UNION SELECT 20 UNION SELECT 30) b) d LEFT JOIN
(SELECT 1 AS id,m FROM
(SELECT 1 m UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) m) m ON d.id=m.id LEFT JOIN
-- This part here > YEAR(CURDATE())=2019.
(SELECT 1 AS id, YEAR(CURDATE() - INTERVAL 1 YEAR) yy
-- Adding '- INTERVAL 1 YEAR' means that it will reduce 1 year or YEAR(CURDATE()).
-- Hence it will become '2018'.
-- If you want future year, just change it to '+ INTERVAL 1 YEAR' = 2020 or '+ INTERVAL 2 YEAR' = 2021.
) yy ON d.id=yy.id WHERE days BETWEEN 1 AND 31 ORDER BY dates;
请注意,这只是用于检查的临时表,因为此处的日期都在1到31之间。这意味着每个月的最后日期是201X-XX-31,无论是2月还是6月。这里的主要目的是将其仅用于快速比较。有多种方法可以确保所有这些日期都将遵循日历中的正确日期,但查询会很复杂。