【问题标题】:SQL - Group by to get sum but also return a row if the sum is 0SQL - 分组以获取总和,但如果总和为 0,则返回一行
【发布时间】:2023-03-04 05:25:01
【问题描述】:

我有下表:

ID BuyOrSell Total
4    B         10
4    B         11
4    S         13
4    S         29
8    B         20
9    S         23

我要做的是为每个 ID 设置 B 和 S 列的总和,如果 ID 没有 B 或 S 的行为 0,那么预期输出将是

ID BuyOrSell Total
4    B         21
4    S         42
8    B         20
8    S          0
9    S         23
9    B          0

我已经尝试过了,它有点像我所追求的,但不完全是:

DECLARE @Temp Table (ID int, BuyOrSell VARCHAR(1), charge Decimal)
INSERT INTO @Temp 
SELECT 4, 'B', 10 UNION ALL
SELECT 4, 'B', 11 UNION ALL
SELECT 4, 'S', 13 UNION ALL
SELECT 4, 'S', 29 UNION ALL
SELECT 8, 'B', 20 UNION ALL
SELECT 9, 'S', 23 

;With Results AS
(
SELECT ID,
       BuyOrSell,
       SUM(charge) AS TOTAL
FROM @Temp 
Group by ID, BuyOrSell
)
Select t.*,max(
                case when BuyOrSell = 'B' then 'Bfound' 
                end) over (partition by ID) as ref
            ,max(
                case when BuyOrSell = 'S' then 'Sfound' 
                end) over (partition by ID) as ref
FROM Results t;

谢谢

【问题讨论】:

    标签: sql sql-server group-by sql-server-2012


    【解决方案1】:

    试试这个:

    ;WITH CTE(ID, BuyOrSell) AS(
        SELECT 
            ID, T.BuyOrSell 
        FROM @Temp
        CROSS JOIN(
            SELECT 'B' UNION ALL SELECT 'S'
        )T(BuyOrSell)
        GROUP BY ID, T.BuyOrSell
    )
    SELECT
        C.ID,
        C.BuyOrSell,
        Total = ISNULL(SUM(T.charge), 0)
    FROM CTE C
    LEFT JOIN @Temp T
        ON T.ID = C.ID
        AND T.BuyOrSell = C.BuyOrSell
    GROUP BY C.ID, C.BuyOrSell
    ORDER BY C.ID, C.BuyOrSell
    

    【讨论】:

    • 没问题,很高兴能帮上忙。
    【解决方案2】:

    @03Usr,尽管你的问题已经得到解答,请试试这个:

             SELECT two.ID,
                    two.BuyOrSell,
                    ISNULL (one.Total, 0) Total
               FROM
            (SELECT ID,
                    BuyOrSell,
                    SUM (Total) Total
               FROM @Temp
           GROUP BY ID, BuyOrSell) one
    LEFT OUTER JOIN
            (SELECT ID,
                    BuyOrSell
               FROM @Temp
           GROUP BY ID,
                    BuyOrSell) two
                 ON one.ID = two.ID
                AND one.BuyOrSell = two.BuyOrSell;
    

    【讨论】:

      【解决方案3】:

      这是一个棘手的连接解决方​​案:

      SELECT t1.ID, 
             v.l as BuyOrSell, 
             SUM(CASE WHEN t1.BuyOrSell = v.l THEN t1.charge ELSE 0 END) AS Total
      FROM @Temp t1
      JOIN (VALUES('B'),('S')) v(l) 
        ON t1.BuyOrSell = CASE WHEN EXISTS(SELECT * FROM @Temp t2 
                                           WHERE t2.ID = t1.ID AND t2.BuyOrSell <> t1.BuyOrSell) 
                               THEN v.l ELSE t1.BuyOrSell END
      GROUP BY t1.ID, v.l
      ORDER BY t1.ID, v.l
      

      输出:

      ID  l   Total
      4   B   21
      4   S   42
      8   B   20
      8   S   0
      9   B   0
      9   S   23
      

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 2022-01-24
        • 1970-01-01
        • 2021-09-05
        • 1970-01-01
        • 1970-01-01
        • 2018-08-20
        • 1970-01-01
        • 2019-01-24
        相关资源
        最近更新 更多