如何在日期类型的两列之间获取数据

时间:2019-04-10 05:30:38

标签: mysql

我有一个用于存储事件数据的表,其中包含以下两个条目

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。

3 个答案:

答案 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

有关演示,请点击以下链接:

  

this document

答案 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月。这里的主要目的是将其仅用于快速比较。有多种方法可以确保所有这些日期都将遵循日历中的正确日期,但查询会很复杂。