SQL 服务器 SUM IF 使用具有多个条件的 Window 函数

SQL Server SUM IF using Window function with multiple conditions

编辑:原始问题名称'SQL Server SUM records only Group By certain values'。精了,既然知道要找什么了。

我目前正在尝试使用 OVERPARITION BY 根据条件进行聚合,但是我不知道如何整合最后一个条件。

它应该做什么: 如果每个 CONTRACTIDVALIDFROMVALIDTO 在列 RENTALCOSTTYPEID 中有一个值 'H104' 然后汇总所有 AMOUNT 具有 RENTALCOSTTYPEID 以 'H' 开头的值。 ELSE 显示 AMOUNT 而不聚合。

当每个 CONTRACTIDVALIDFROMVALIDTO 有一个值 'H104' 时,我当前的代码有效。但是,如果根据 CONTRACTIDVALIDFROMVALIDTO 没有值 '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