从case语句添加行 - SQL Server

时间:2018-01-11 15:21:35

标签: sql sql-server tsql

我目前的结果是这个

我每月都会比较两张表中的总数。当两个表之间的总数不同时,我想将差异添加到另一个列

| MonthYear | Person | Table1 Amount | Table2 Amount | Unknown |
+-----------+--------+---------------+---------------+---------+
|    Jun-17 |    Tom |           100 |           125 |      25 |
|    Nov-17 |        |            50 |           150 |     100 |
|    Sep-17 |    Ben |            50 |            50 |       0 |

我已经实现了但是如何将case语句添加为行而不是列,例如像这样的输出。然后,我可以通过'未知'类别。

| MonthYear | Person | Table1 Amount | Table2 Amount |  Difference |
+-----------+--------+---------------+---------------+-------------+
|    Jun-17 |    Tom |           100 |           125 |          25 |
|    Nov-17 |        |            50 |           150 |         100 |
|    Sep-17 |    Ben |            50 |            50 |           0 |
|    Jun-17 |Unknown |            25 |          Null |           0 |
|    Nov-17 |Unknown |           100 |          Null |           0 |

可以这样做吗?任何帮助,将不胜感激。感谢

SQL FIDDLE - http://sqlfiddle.com/#!6/8843b/24

2 个答案:

答案 0 :(得分:1)

SELECT  
    T1.MonthYear, T1.Person,
    min(T1.Amount) AS "Table1 Amount", min(T2.Amount) AS "Table2 Amount",
    min(CASE WHEN T1.Amount <> T2.Amount 
             THEN ABS(T1.Amount - T2.Amount)
             ELSE 0 END) AS [Difference]
FROM Invoice AS T1 LEFT OUTER JOIN Invoice AS T2
    ON T1.Code1 = T2.Code1 AND T1.InvoiceNumber = T2.InvoiceNumber AND T1.Person <> ''
GROUP BY T1.MonthYear, T1.Person;

就个人而言,我不喜欢将sum()用作虚拟聚合,因此我将其更改为min()

实际上我真的认为你根本不需要分组。如果每个代码和发票确实有多个匹配的行,那么连接最终会将这些行乘以交叉产品:

SELECT  
    t1.MonthYear, T1.Person, t1.Amount AS [Table1 Amount], t2.Amount AS [Table2 Amount],
    CASE WHEN T1.Amount <> T2.Amount 
         THEN ABS(T1.Amount - T2.Amount) ELSE 0 END AS [Difference]
FROM Invoice AS T1 LEFT OUTER JOIN Invoice AS T2
    ON T1.Code1 = T2.Code1 AND T1.InvoiceNumber = T2.InvoiceNumber AND t1.Person <> ''
ORDER BY CASE WHEN t1.Person <> '' then 0 else 1 end, T1.MonthYear, t1.Person;

答案 1 :(得分:0)

SELECT  
  T2.MonthYear
  , MAX(T1.Person) AS Person
  , SUM(T1.Amount) AS [Table1 Amount]
  , SUM(T2.Amount) AS [Table2 Amount]
  , CASE
        WHEN SUM(T1.Amount) <> SUM(T2.Amount)
        THEN ABS(SUM(T1.Amount) - SUM(T2.Amount)) ELSE 0 
  END AS [Difference]
FROM
    Invoice AS T1
    JOIN Invoice2 AS T2
        ON T1.Code1 = T2.Code1
        AND T1.InvoiceNumber = T2.InvoiceNumber
GROUP BY T2.MonthYear

UNION ALL

SELECT
    T2.MonthYear
    , 'Unknown' AS Person
    , ABS(SUM(T1.Amount) - SUM(T2.Amount)) AS [Table1 Amount]
  , NULL AS [Table2 Amount]
    , 0 AS [Difference]
FROM
    Invoice AS T1
    JOIN Invoice2 AS T2
        ON T1.Code1 = T2.Code1
        AND T1.InvoiceNumber = T2.InvoiceNumber
GROUP BY T2.MonthYear
HAVING SUM(T1.Amount) <> SUM(T2.Amount);