如何在结果表中添加缺少的日期?

时间:2014-03-31 19:12:15

标签: sql sqlite

我有一张桌子:

accdate (DATETIME) | value (INT)
-------------------+------------
                   |

accdate-column包含有关小时粒度的数据集。这意味着,格式为YYYY-mm-dd HH:00:00的日期时间。如果我使用SELECT * FROM mytable ORDER BY accdate ASC查看表格,我会通过accdate获得一个有序的表格。但mytable不包含第一行和最后一行之间的所有可能日期和小时(在我的程序未运行的时间内缺少某些日期)。我希望在第一行和最后一行之间具有所有可能日期+小时组合的默认值。

我知道这可以通过使用另一个表的LEFT JOIN来解决,该表包含此范围内的所有可能日期。 但是我如何在SQL语句中构造这样的表?我认为如果我可以解决查询中的问题,用虚拟数据填充表是没有意义的。

示例:

accdate (DATETIME)   | value (INT)
---------------------+------------
2011-11-11 19:00:00  |  50
2011-11-11 20:00:00  |  53
2011-11-11 22:00:00  |  16
2011-11-12 06:00:00  |  15
2011-11-12 07:00:00  |  150

2011-11-11 21:00:00之间的日期和下午23点至凌晨5点的范围缺失。对于这些日期,结果表中应该有一行(在值列中包含0)。

我希望你理解我的问题。如果不清楚,请发表评论。谢谢。

2 个答案:

答案 0 :(得分:1)

使用SQLite 3.8.3或更高版本,您可以使用common table expression从无到有生成值:

WITH RECURSIVE AllDates(accdate)
AS (VALUES('2011-11-11 00:00:00')
    UNION ALL
    SELECT datetime(accdate, '+1 hour')
    FROM AllDates
    WHERE accdate < '2011-11-12 10:00:00')
SELECT AllHours.accdate,
       MyTable.value
FROM AllHours
LEFT JOIN MyTable USING (accdate)

答案 1 :(得分:0)

我能想到的唯一方法是使用同一个表的左连接,添加到连接上的所需字段,并将结果与​​实际结果结合起来以完成集合:

示例设置:

CREATE TABLE tmp (
    id INT IDENTITY,
    number INT
);

-- insert some incomplete sequenced values
INSERT INTO tmp (number) VALUES(1);
INSERT INTO tmp (number) VALUES(3);
INSERT INTO tmp (number) VALUES(4);

示例查询:

-- select your actual data
SELECT number
FROM tmp

UNION

-- select the missing data
SELECT a.number + 1
FROM tmp a
LEFT JOIN tmp b ON a.number + 1 = b.number
WHERE b.id IS NULL

-- order the complete set
ORDER BY number ASC;

如果您的结果中有多个缺失值(例如:1和4),这将无效,但如果您的数据在每个结果之间仅缺少一个小时,则此工作就像一个魅力