不同条件加入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
我希望在不同的条件下加入 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