SQL Server SUM IF 使用具有多个条件的窗口函数
Posted
技术标签:
【中文标题】SQL Server SUM IF 使用具有多个条件的窗口函数【英文标题】:SQL Server SUM IF using Window function with multiple conditions 【发布时间】:2020-09-01 10:50:05 【问题描述】:编辑:原始问题名称“SQL Server SUM 记录仅按某些值分组”。精致,因为现在知道要寻找什么。
我目前正在尝试使用OVER
和PARITION BY
根据条件进行聚合,但是我不知道如何整合最后一个条件。
它应该做什么:
如果每个CONTRACTID
、VALIDFROM
、VALIDTO
在RENTALCOSTTYPEID
列中有一个值“H104”
然后聚合所有AMOUNT
具有以“H”开头的RENTALCOSTTYPEID
值。 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 |
+------------+------------------+------------+------------+---------+---------+-----------+
【问题讨论】:
您可以尝试将您的查询用作子查询并添加一个列,例如CASE WHEN costtype = N'H107' THEN amount ELSE 0 END AS amountH107
,然后创建一个查询和SUM
这个新列...
您可以在聚合函数中添加case
表达式。看到这个similar question。
我快到了。编辑了我的帖子(见下文)。以下代码几乎可以满足我的所有需求:CASE WHEN C.RENTALCOSTTYPEID = 'H104' THEN SUM(CASE WHEN C.RENTALCOSTTYPEID LIKE 'H%' THEN C.AMOUNT ELSE 0 END) OVER (PARTITION BY C.CONTRACTID, C.VALIDFROM, C.VALIDTO) ELSE SUM(C.RENTALCOSTTYPEID LIKE 'H%' THEN 0 ELSE c.amount END) OVER (Partition by C.RENTALCOSTTYPEID, C.CONTRACTID, C.VALIDFROM, C.VALIDTO) END AS TESTCOLUMN跨度>
为什么前三行有不同的ENDRESULT
?他们有相同的CONTRACTID
、VALIDFROM
和VALIDTO
,而且他们在RENTALCOSTTYPEID
列中有一个“H104”不应该都是 446.72?
【参考方案1】:
您正试图在同一行显示聚合值和非聚合值。虽然在单个 select
语句中实现这一点可能是可能的,但在一个查询中组合几个 select
会更容易。
例如,如果您计算rentalcosttypeid H%
行的总和,其中H104
行在common table expression (CTE) 中,那么您可以稍后加入这些结果。
样本数据
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 IF 使用具有多个条件的窗口函数的主要内容,如果未能解决你的问题,请参考以下文章
SQL中多分支If语句的性能(Sql Server 2008)
ms sql server字符串与另一个具有多个值的字符串进行比较
SQL Server:使用具有相同 OVER 子句的多个聚合/分析函数?