我有一张桌子:
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)。
我希望你理解我的问题。如果不清楚,请发表评论。谢谢。
答案 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),这将无效,但如果您的数据在每个结果之间仅缺少一个小时,则此工作就像一个魅力