SQL 服务器 SUM IF 使用具有多个条件的 Window 函数
SQL Server SUM IF using Window function with multiple conditions
编辑:原始问题名称'SQL Server SUM records only Group By certain values'。精了,既然知道要找什么了。
我目前正在尝试使用 OVER
和 PARITION BY
根据条件进行聚合,但是我不知道如何整合最后一个条件。
它应该做什么:
如果每个 CONTRACTID
、VALIDFROM
、VALIDTO
在列 RENTALCOSTTYPEID
中有一个值 'H104'
然后汇总所有 AMOUNT
具有 RENTALCOSTTYPEID
以 'H' 开头的值。 ELSE 显示 AMOUNT
而不聚合。
当每个 CONTRACTID
、VALIDFROM
、VALIDTO
有一个值 'H104' 时,我当前的代码有效。但是,如果根据 CONTRACTID
、VALIDFROM
、VALIDTO
没有值 'H104',它会给出“0”而不是 AMOUNT
查看代码,它显然放置了“0”,但如果我更改此值,它会弄乱有值 'H104' 的字段。如何将此条件集成到以下代码中?
SELECT
CONTRACTID
,RENTALCOSTTYPEID
,VALIDFROM
,VALIDTO
,AMOUNT
,CASE
WHEN RENTALCOSTTYPEID = 'H104'
THEN SUM(CASE WHEN RENTALCOSTTYPEID LIKE 'H%' THEN AMOUNT ELSE 0 END) OVER (PARTITION BY CONTRACTID, VALIDFROM, VALIDTO)
ELSE SUM(CASE WHEN RENTALCOSTTYPEID LIKE 'H%' THEN 0 ELSE AMOUNT END) OVER (PARTITION BY RENTALCOSTTYPEID, CONTRACTID, VALIDFROM, VALIDTO)
END AS TESTCOLUMN
FROM PMCCONTRACTLINE
第 CURRENT
列包含我当前的结果
第 ENDRESULT
列包含我希望的结果
+------------+------------------+------------+------------+---------+---------+-----------+
| CONTRACTID | RENTALCOSTTYPEID | VALIDFROM | VALIDTO | AMOUNT | CURRENT | ENDRESULT |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC018453 | H104 | 2020-07-01 | 2021-01-01 | 775.08 | 446.72 | 446.72 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC018453 | H110 | 2020-07-01 | 2021-01-01 | -328.36 | 0.00 | 0.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC018453 | V446 | 2020-07-01 | 2021-01-01 | 48.00 | 48.00 | 48.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC055533 | H105 | 2020-07-01 | 2021-01-01 | 330.00 | 0.00 | 330.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC055533 | H105H | 2019-07-01 | 2020-06-30 | 330.00 | 0.00 | 330.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | H104 | 2020-06-03 | 2021-01-01 | 867.00 | 867.00 | 867.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | S468 | 2020-06-03 | 2021-01-01 | 2.00 | 2.00 | 2.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | S484 | 2020-06-03 | 2021-01-01 | 1.00 | 1.00 | 1.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | S488 | 2020-06-03 | 2021-01-01 | 0.50 | 0.50 | 0.50 |
+------------+------------------+------------+------------+---------+---------+-----------+
您正试图在同一行上显示聚合值和non-aggregated 个值。虽然在单个 select
语句中实现这一点是可能的,但在一个查询中组合几个 select
更容易。
例如,如果您在 common table expression (CTE) 中计算其中有 H104
行的 rentalcosttypeid H%
行的总和,那么您可以加入那些稍后出结果。
示例数据
declare @PMCCONTRACTLINE table
(
CONTRACTID nvarchar(10),
RENTALCOSTTYPEID nvarchar(5),
VALIDFROM date,
VALIDTO date,
AMOUNT money
);
insert into @PMCCONTRACTLINE (CONTRACTID, RENTALCOSTTYPEID, VALIDFROM, VALIDTO, AMOUNT) values
('HC018453', 'H104', '2020-07-01', '2021-01-01', 775.08 ),
('HC018453', 'H110', '2020-07-01', '2021-01-01', -328.36),
('HC018453', 'V446', '2020-07-01', '2021-01-01', 48.00 ),
('HC055533', 'H105', '2020-07-01', '2021-01-01', 330.00 ),
('HC055533', 'H105H', '2019-07-01', '2020-06-30', 330.00 ),
('HC103696', 'H104', '2020-06-03', '2021-01-01', 867.00 ),
('HC103696', 'S468', '2020-06-03', '2021-01-01', 2.00 ),
('HC103696', 'S484', '2020-06-03', '2021-01-01', 1.00 ),
('HC103696', 'S488', '2020-06-03', '2021-01-01', 0.50 );
解决方案
将 cte_SumH104
定义为 H%
行的结果集,其中有 H104
行具有相同的 ContractID。
with cte_SumH104 as
(
select cl.CONTRACTID, sum(cl.AMOUNT) as 'SUMH'
from @PMCCONTRACTLINE cl
where cl.RENTALCOSTTYPEID like 'H%'
and exists ( select top 1 'x'
from @PMCCONTRACTLINE clh104
where clh104.CONTRACTID = cl.CONTRACTID
and clh104.RENTALCOSTTYPEID = 'H104' )
group by cl.CONTRACTID
)
select cl.*,
s.SUMH,
case
when cl.RENTALCOSTTYPEID = 'H104' then s.SUMH
when cl.RENTALCOSTTYPEID like 'H%' and s.SUMH is not null then 0
else cl.AMOUNT
end as 'TEST'
from @PMCCONTRACTLINE cl
left join cte_SumH104 s
on s.CONTRACTID = cl.CONTRACTID;
结果
CONTRACTID RENTALCOSTTYPEID VALIDFROM VALIDTO AMOUNT SUMH TEST
----------- ----------------- ----------- ----------- --------- -------- --------
HC018453 H104 2020-07-01 2021-01-01 775,08 446,72 446,72
HC018453 H110 2020-07-01 2021-01-01 -328,36 446,72 0,00
HC018453 V446 2020-07-01 2021-01-01 48,00 446,72 48,00
HC055533 H105 2020-07-01 2021-01-01 330,00 NULL 330,00
HC055533 H105H 2019-07-01 2020-06-30 330,00 NULL 330,00
HC103696 H104 2020-06-03 2021-01-01 867,00 867,00 867,00
HC103696 S468 2020-06-03 2021-01-01 2,00 867,00 2,00
HC103696 S484 2020-06-03 2021-01-01 1,00 867,00 1,00
HC103696 S488 2020-06-03 2021-01-01 0,50 867,00 0,50
编辑:原始问题名称'SQL Server SUM records only Group By certain values'。精了,既然知道要找什么了。
我目前正在尝试使用 OVER
和 PARITION BY
根据条件进行聚合,但是我不知道如何整合最后一个条件。
它应该做什么:
如果每个 CONTRACTID
、VALIDFROM
、VALIDTO
在列 RENTALCOSTTYPEID
中有一个值 'H104'
然后汇总所有 AMOUNT
具有 RENTALCOSTTYPEID
以 'H' 开头的值。 ELSE 显示 AMOUNT
而不聚合。
当每个 CONTRACTID
、VALIDFROM
、VALIDTO
有一个值 'H104' 时,我当前的代码有效。但是,如果根据 CONTRACTID
、VALIDFROM
、VALIDTO
没有值 'H104',它会给出“0”而不是 AMOUNT
查看代码,它显然放置了“0”,但如果我更改此值,它会弄乱有值 'H104' 的字段。如何将此条件集成到以下代码中?
SELECT
CONTRACTID
,RENTALCOSTTYPEID
,VALIDFROM
,VALIDTO
,AMOUNT
,CASE
WHEN RENTALCOSTTYPEID = 'H104'
THEN SUM(CASE WHEN RENTALCOSTTYPEID LIKE 'H%' THEN AMOUNT ELSE 0 END) OVER (PARTITION BY CONTRACTID, VALIDFROM, VALIDTO)
ELSE SUM(CASE WHEN RENTALCOSTTYPEID LIKE 'H%' THEN 0 ELSE AMOUNT END) OVER (PARTITION BY RENTALCOSTTYPEID, CONTRACTID, VALIDFROM, VALIDTO)
END AS TESTCOLUMN
FROM PMCCONTRACTLINE
第 CURRENT
列包含我当前的结果
第 ENDRESULT
列包含我希望的结果
+------------+------------------+------------+------------+---------+---------+-----------+
| CONTRACTID | RENTALCOSTTYPEID | VALIDFROM | VALIDTO | AMOUNT | CURRENT | ENDRESULT |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC018453 | H104 | 2020-07-01 | 2021-01-01 | 775.08 | 446.72 | 446.72 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC018453 | H110 | 2020-07-01 | 2021-01-01 | -328.36 | 0.00 | 0.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC018453 | V446 | 2020-07-01 | 2021-01-01 | 48.00 | 48.00 | 48.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC055533 | H105 | 2020-07-01 | 2021-01-01 | 330.00 | 0.00 | 330.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC055533 | H105H | 2019-07-01 | 2020-06-30 | 330.00 | 0.00 | 330.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | H104 | 2020-06-03 | 2021-01-01 | 867.00 | 867.00 | 867.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | S468 | 2020-06-03 | 2021-01-01 | 2.00 | 2.00 | 2.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | S484 | 2020-06-03 | 2021-01-01 | 1.00 | 1.00 | 1.00 |
+------------+------------------+------------+------------+---------+---------+-----------+
| HC103696 | S488 | 2020-06-03 | 2021-01-01 | 0.50 | 0.50 | 0.50 |
+------------+------------------+------------+------------+---------+---------+-----------+
您正试图在同一行上显示聚合值和non-aggregated 个值。虽然在单个 select
语句中实现这一点是可能的,但在一个查询中组合几个 select
更容易。
例如,如果您在 common table expression (CTE) 中计算其中有 H104
行的 rentalcosttypeid H%
行的总和,那么您可以加入那些稍后出结果。
示例数据
declare @PMCCONTRACTLINE table
(
CONTRACTID nvarchar(10),
RENTALCOSTTYPEID nvarchar(5),
VALIDFROM date,
VALIDTO date,
AMOUNT money
);
insert into @PMCCONTRACTLINE (CONTRACTID, RENTALCOSTTYPEID, VALIDFROM, VALIDTO, AMOUNT) values
('HC018453', 'H104', '2020-07-01', '2021-01-01', 775.08 ),
('HC018453', 'H110', '2020-07-01', '2021-01-01', -328.36),
('HC018453', 'V446', '2020-07-01', '2021-01-01', 48.00 ),
('HC055533', 'H105', '2020-07-01', '2021-01-01', 330.00 ),
('HC055533', 'H105H', '2019-07-01', '2020-06-30', 330.00 ),
('HC103696', 'H104', '2020-06-03', '2021-01-01', 867.00 ),
('HC103696', 'S468', '2020-06-03', '2021-01-01', 2.00 ),
('HC103696', 'S484', '2020-06-03', '2021-01-01', 1.00 ),
('HC103696', 'S488', '2020-06-03', '2021-01-01', 0.50 );
解决方案
将 cte_SumH104
定义为 H%
行的结果集,其中有 H104
行具有相同的 ContractID。
with cte_SumH104 as
(
select cl.CONTRACTID, sum(cl.AMOUNT) as 'SUMH'
from @PMCCONTRACTLINE cl
where cl.RENTALCOSTTYPEID like 'H%'
and exists ( select top 1 'x'
from @PMCCONTRACTLINE clh104
where clh104.CONTRACTID = cl.CONTRACTID
and clh104.RENTALCOSTTYPEID = 'H104' )
group by cl.CONTRACTID
)
select cl.*,
s.SUMH,
case
when cl.RENTALCOSTTYPEID = 'H104' then s.SUMH
when cl.RENTALCOSTTYPEID like 'H%' and s.SUMH is not null then 0
else cl.AMOUNT
end as 'TEST'
from @PMCCONTRACTLINE cl
left join cte_SumH104 s
on s.CONTRACTID = cl.CONTRACTID;
结果
CONTRACTID RENTALCOSTTYPEID VALIDFROM VALIDTO AMOUNT SUMH TEST
----------- ----------------- ----------- ----------- --------- -------- --------
HC018453 H104 2020-07-01 2021-01-01 775,08 446,72 446,72
HC018453 H110 2020-07-01 2021-01-01 -328,36 446,72 0,00
HC018453 V446 2020-07-01 2021-01-01 48,00 446,72 48,00
HC055533 H105 2020-07-01 2021-01-01 330,00 NULL 330,00
HC055533 H105H 2019-07-01 2020-06-30 330,00 NULL 330,00
HC103696 H104 2020-06-03 2021-01-01 867,00 867,00 867,00
HC103696 S468 2020-06-03 2021-01-01 2,00 867,00 2,00
HC103696 S484 2020-06-03 2021-01-01 1,00 867,00 1,00
HC103696 S488 2020-06-03 2021-01-01 0,50 867,00 0,50