带JOIN的SQL LAG函数 - 即使数据为空,也必须从前一行提取数据

时间:2016-04-26 02:26:05

标签: sql sql-server sql-server-2012

我有三张桌子:

1)Calendar

  • 此表每个日期都有一个条目(这实际上是包含每日记录的较大表的一部分 - 我正在简化此上下文)

2)Reading_Type

  • Reading_Type_ID
  • Type_Name

3)Readings

  • Reading_ID
  • Reading_Type_ID
  • Reading_Date
  • Reading

对于给定的Reading_Type_IDReading_Date,只允许一个条目,但并非所有日期都有读数。

我需要一个返回Readings的所有数据的查询,以及昨天的Reading_Type_ID读数。

如果前一天(昨天)没有阅读,Yesterday_Reading应为0(只需从表格中的上一行读取该行,如果该行为>提前1天。

到目前为止我所拥有的:

SELECT
      r.Reading_ID
    , r.Reading_Type_ID
    , r.Reading
    , r.Reading_Date
    , LAG(r.Reading, 1, 0)
        OVER (PARTITION BY r.Reading_Type_ID ORDER BY r.Reading_Date)
        AS Yesterday_Reading
FROM
    Calendar c
LEFT JOIN
    Readings r ON c.Date = r.Reading_Date

此LAG函数从Readings表中的最后一行(按日期)拉出,而不是严格来自“昨天”。我尝试了一些排列(ORDER BY c.Date,从c添加行到SELECT子句等),但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

问题是您需要每个Reading_Type_ID的完整日历期。您可以使用CROSS JOIN

执行此操作
SELECT r.Reading_ID, rr.Reading_Type_ID, r.Reading, r.Reading_Date,
       LAG(r.Reading, 1, 0) OVER (PARTITION BY rr.Reading_Type_ID ORDER BY r.Reading_Date
                                 ) as Yesterday_Reading
FROM Calendar c CROSS JOIN
     (SELECT DISTINCT r.Reading_Type_ID FROM Readings r) rr LEFT JOIN
     Readings r
     ON c.Date = r.Reading_Date AND r.Reading_Type_ID = rr.Reading_Type_ID;