将SQL表中的数据与同一表中的历史数据进行比较

时间:2015-10-11 10:49:46

标签: sql sqlite

我有一个表格,其中包含按月和年汇总的一些数据:

Date             Value
----------------------
2014-03             24
2014-04             23
2014-05             24
2014-06             23
... (data rows for 2014-07 through 2015-07)
2015-08             28
2015-09             27
2015-10             19

我想构建一个视图,给定年份显示该年的值,以及过去一年的相应数据。对于没有数据的月份(如2015年11月和12月),我仍然希望拥有行,当前年份的值为零,以及上一年的历史值。反过来也适用,如果上个月没有来自该月的数据,该视图仍应显示月份(如示例中的2014年1月和2月),但值为0:

Date             Value        Value last year
---------------------------------------------
2015-12              0                     12
2015-11              0                     11
2015-10             19                     29
2015-09             27                     11
2015 08             28                     18
2015-07             25                     17
2015-06             23                     23
2015-05             18                     24
2015-04             24                     23
2015-03             24                     24
2015-02             23                      0
2015-01             11                      0

有没有直接的方法来创建这样的视图?我无法将视图包含在2015年没有数据的最后两个月中。使用左外连接的天真方法不包括2015年现有数据的行。如何“伪造”数据在当年没有数据的几个月?

在SQLITE语法中,天真的查询看起来像这样。

select A.DATE, A.VALUE, B.VALUE FROM
AGGREGATOR A
LEFT OUTER JOIN AGGREGATOR B 
ON A.DATE = date(B.DATE, '+1 year');

任何指针都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是使用派生表中的联合查询创建一个包含所有日期的虚拟表,并将其用作左联接的主要日期源。

这样的事情应该有效:

SELECT SRC.DATE, A.VALUE, B.VALUE 
FROM
(
    SELECT '2015-01-01' AS DATE UNION ALL 
    SELECT '2015-02-01' UNION ALL 
    SELECT '2015-03-01' UNION ALL 
    SELECT '2015-04-01' UNION ALL 
    SELECT '2015-05-01' UNION ALL 
    SELECT '2015-06-01' UNION ALL 
    SELECT '2015-07-01' UNION ALL 
    SELECT '2015-08-01' UNION ALL 
    SELECT '2015-09-01' UNION ALL 
    SELECT '2015-10-01' UNION ALL 
    SELECT '2015-11-01' UNION ALL 
    SELECT '2015-12-01'
) SRC
LEFT JOIN AGGREGATOR A ON SRC.DATE = A.DATE
LEFT JOIN AGGREGATOR B ON SRC.DATE = DATE(B.DATE, '+1 year');

我假设你的日期列实际上包含了这一天以及date函数仅在年月时不起作用,但如果不是,你应该能够根据具体情况调整查询设置。