SQL - 分组获取总和但如果总和为0则返回一行

时间:2014-10-24 08:17:32

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

我有下表:

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;

由于

3 个答案:

答案 0 :(得分:3)

试试这个:

;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

答案 1 :(得分:0)

@ 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;

答案 2 :(得分:0)

这是一个棘手的加入解决方案:

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