不同条件加入table

Joining table of different conditions

我希望在不同的条件下加入 table 两次。请阅读下面的示例,即使上面几行没有意义。我尝试使用 CASE WHEN 左连接相同的 table,但我没有得到所需的输出,而且我是 SQL.

的新手

有一个名为 MeterReading 的 table,它具有特定月份的抄表值。我想创建一个连接 table,其中包含当月的抄表以及上个月的抄表值。

月份和年份是整数值。示例中的所有内容都是整数值。

Table 抄表

MeterID 年值 月值 读数值 使用值
1 2020 1 100 150
2 2020 2 120 140
3 2020 3 180 200
...
12 2020 12 140 200
13 2021 1 230 170
14 2021 2 120 100

我正在寻找的输出是这样的:

MeterID 年值 月值 读数值 使用值 前值 PrevUsingVal
1 2020 1 100 150
2 2020 2 120 140 100 150
3 2020 3 180 200 120 140
...
12 2020 12 140 200 ... ...
13 2021 1 230 170 140 200
14 2021 2 120 100 230 170

另外需要注意的是,由于年月都是整数,所以2021年01的前一个就是2020年12。

我尝试的查询是(同样,我对 SQL 还是很陌生):

SELECT
MR.meterid ,
MR.year_val,
MR.month_val,
MR.reading_val,
MR.using_val,
TMR.Meterid,
TMR.YV2,
TMR.MV2,
TMR.RV1,
TMR.UV2,
0 AS DelFlag
From MeterReading MR
LEFT JOIN
(
    SELECT
    MR.meterid,
    MR.Reading_val AS RV1 ,
    MR.using_val AS UV2,
    CASE WHEN MR.Month_val = 1 THEN 12 ELSE MR.Month_val - 1  END AS MV2,
    CASE WHEN MR.month_val = 1 THEN MR.year_val + 1 ELSE MR.year_val END AS YV2
    FROM MeterReading MR
) TMR
ON
MR.meterid = TMR.meterid AND
MR.year_val = TMR.YV2 AND
MR.month_val = TMR.MV2

我没有得到预期的结果。请用简单的解释指导我。

LAG()对于简单的情况应该这样做。但是,如果您想要更大的灵活性,应该首选使用 JOIN。您可以尝试以下方法:

SELECT          currentYear.MeterID, currentYear.YearVal, currentYear.MonthVal, currentYear.ReadingVal, currentYear.UsingVal, previousYear.ReadingVal AS PrevVal, previousYear.UsingVal AS PrevUsingVal
FROM            #MeterReading currentYear
LEFT JOIN       #MeterReading previousYear ON (currentYear.YearVal = previousYear.YearVal AND (currentYear.MonthVal - 1) = previousYear.MonthVal)
WHERE           currentYear.MonthVal != 1
UNION
SELECT          currentYear.MeterID, currentYear.YearVal, currentYear.MonthVal, currentYear.ReadingVal, currentYear.UsingVal, previousYear.ReadingVal AS PrevVal, previousYear.UsingVal AS PrevUsingVal
FROM            #MeterReading currentYear
LEFT JOIN       #MeterReading previousYear ON ((currentYear.YearVal - 1) = previousYear.YearVal) AND (previousYear.MonthVal = 12)
WHERE           currentYear.MonthVal = 1

ORDER BY        currentYear.YearVal ASC, currentYear.MonthVal ASC

如果每个月都有数据,可以使用简单的滞后:

select mr.*,
       lag(readingval) over (order by yearval, monthval) as prev_readingval,
       lag(usingval) over (order by yearval, monthval) as prev_usingval
from MeterReading mr;

如果您可能会丢失数据并且希望将其视为 NULL(而不是转到数据中的上一个月),您仍然可以使用 window 函数,但使用 range window 帧数:

select mr.*,
       sum(readingval) over (order by yearval * 12 + monthval
                             range between 1 preceding and 1 preceding
                            ) as prev_readingval,
       lag(usingval) over (order by yearval * 12 + monthval
                           range between 1 preceding and 1 preceding
                          ) as prev_usingval
from MeterReading mr;

我以一种非常初级的方式做到了这一点,通过在具有 [CASE WHEN] 的条件下左连接相同的 table 对于月份和年份的边界情况(即 2020 年 1 月的前一个值应该获取值2019 年 12 月),

查询:

SELECT
  TMR.MeterID
, TMR.YearVal
, TMR.MonthVal
, TMR.ReadingVal AS ReadingVal
, TMR.UsingVal AS UsingVal
, TMR2.ReadingVal AS PrevReadVal
, TMR2.Using AS PrevUsingVal
FROM MeterReading TMR
LEFT JOIN 
(
  SELECT
    TMR.MeterID
  , TMR.ReadingVal
  , TMR.UsingVal
  , CASE WHEN TMR.MonthVal = '12' THEN 1 ELSE TMR.MonthVal + 1 END AS MonthVal2
  , CASE WHEN TMR.MonthVal = '12' THEN TMR.YearVal + 1 ELSE TMR.YearVal END AS YearVal2
  FROM MeterReading TMR
) TMR2 ON
TMR.MeterID = TMR2.MeterID
AND TMR.YearVal = TMR2.YearVal2
AND TMR.MonthVal = TMR2.MonthVal2