2

我有 2 列,一个是开始日期,另一个是结束日期。我需要找到两个日期之间的每一天。

需要在另一个带有两个列的表中,一个名称pno是指pno第一个表中的 id,另一个名称是开始日期和结束日期之间的日期。

例如,这可能是我的输入

 
pno 开始日期 结束日期
p1 2012-12-03 2012-12-06     
p2 2013-01-05 2013-01-08
p3 2013-01-15 2012-01-20

这必须是我的输出。

pno 日期
----------
p01 2012-12-03
p01 2012-12-04
p01 2012-12-05
p01 2012-12-06
p02 2013-01-05
p02 2013-01-06
p02 2013-01-07
p02 2013-01-08
p03 2013-01-15
...
4

1 回答 1

5

你可以这样做

SELECT pno, startdate + INTERVAL q.n - 1 DAY dates
  FROM table1 t CROSS JOIN
(
   SELECT a.N + b.N * 10 + 1 n
     FROM 
    (SELECT 0 AS N 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) a
   ,(SELECT 0 AS N 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) b
    ORDER BY n
) q 
 WHERE q.n - 1 <= DATEDIFF(enddate, startdate) 
 ORDER BY pno, dates

子查询生成从 1 到 100 的数字序列。您可以根据需要对其进行调整(如果日期差异跨度大于或小于 100 天),或者如果您执行大量此类操作,则可以将其完全替换为持久的计数(数字)表查询。

输出:

+--------+------------+
| 无 | 日期 |
+--------+------------+
| p1 | 2012-12-03 |
| p1 | 2012-12-04 |
| p1 | 2012-12-05 |
| p1 | 2012-12-06 |
| p2 | 2013-01-05 |
| p2 | 2013-01-06 |
| p2 | 2013-01-07 |
| p2 | 2013-01-08 |
| p3 | 2013-01-15 |
| p3 | 2013-01-16 |
| p3 | 2013-01-17 |
| p3 | 2013-01-18 |
| p3 | 2013-01-19 |
| p3 | 2013-01-20 |
+--------+------------+

这是SQLFiddle演示


更新:创建和填充持久的计数表使用

CREATE TABLE tally (n INT NOT NULL PRIMARY KEY);

INSERT INTO tally (n)
SELECT a.n + b.n * 10 + c.n * 100 + d.n * 1000 + 1 n
 FROM 
(SELECT 0 AS n 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) a
,(SELECT 0 AS n 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) b
,(SELECT 0 AS n 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) c
,(SELECT 0 AS n 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) d
ORDER BY n;

您将在计数表中拥有从 1 到 10000 的数字序列。这将允许您使用超过 27 年的日期范围。

现在查询归结为

SELECT pno, startdate + INTERVAL q.n - 1 DAY dates
  FROM table1 t CROSS JOIN tally q 
 WHERE q.n - 1 <= DATEDIFF(enddate, startdate) 
 ORDER BY pno, dates

这是SQLFiddle演示

于 2013-09-28T07:37:41.367 回答