在相关表上计算聚合函数时,如何避免重复?

时间:2018-07-09 15:42:39

标签: sql sql-server tsql

为了简化我创建这3个表的问题,经常需要对一些相关表进行一些计算:

交易

TransactionId CustomerId  SellerId    NetValue    Taxes
------------- ----------- ----------- ----------- -----------
1             1           2           435         10

交易详细信息

TransactionDetailId TransactionId ItemId      ItemPrice   Qty         IsNew IsOriginal
------------------- ------------- ----------- ----------- ----------- ----- ----------
1                   1             1           40          8           1     1
2                   1             2           50          2           0     1
3                   1             3           15          1           1     0

付款

PaymentId   TransactionId PaymentValue PaymentMethodId
----------- ------------- ------------ ---------------
1           1             50           1
2           1             300          2

现在我需要像这样的单行表:

NewItems    NewItemsValue OriginalItems OriginalItemsValue ItemsValue  TotalItems  Paid        Visa        Cash
----------- ------------- ------------- ------------------ ----------- ----------- ----------- ----------- -----------
9           335           10            420                435         11          350         300         50

我首先尝试过此操作(在应用SUM函数之前):

SELECT
CASE WHEN Detail.IsNew = 1 THEN Detail.Qty END AS NewItems,
CASE WHEN Detail.IsNew = 1 THEN Detail.ItemPrice END AS NewItemsValue,
CASE WHEN Detail.IsOriginal = 1 THEN Detail.Qty END AS OriginalItems,
CASE WHEN Detail.IsOriginal = 1 THEN Detail.ItemPrice END AS OriginalItemsValue,
Pay.PaymentValue AS Paid,
Detail.ItemPrice AS ItemsValue,
Detail.Qty AS TotalItems,
(CASE WHEN Pay.PaymentMethodId=1 THEN Pay.PaymentValue ELSE 0 END) AS Cash,
(CASE WHEN Pay.PaymentMethodId=2 THEN Pay.PaymentValue ELSE 0 END) AS Visa

FROM Transactions AS Trans

JOIN TransactionDetails AS Detail ON Trans.TransactionId = Detail.TransactionId 

JOIN Payments AS Pay 
 ON Trans.TransactionId = Pay.TransactionId

,但是有重复项。现在,我唯一的选择是将三个表与UNION联接,但这似乎是一个不好的选择,是否有更好的解决方案?

2 个答案:

答案 0 :(得分:0)

您需要aggregation,但有条件的

SELECT SUM(CASE WHEN Detail.IsNew = 1 THEN Detail.Qty ELSE 0 END) AS NewItems,
       SUM(CASE WHEN Detail.IsNew = 1 THEN Detail.ItemPrice ELSE 0 END) AS NewItemsValue,
       SUM(CASE WHEN Detail.IsOriginal = 1 THEN Detail.Qty END) AS OriginalItems,
       SUM(CASE WHEN Detail.IsOriginal = 1 THEN Detail.ItemPrice ELSE 0 END) AS OriginalItemsValue,
       SUM(Pay.PaymentValue) AS Paid,
       SUM(Detail.ItemPrice) AS ItemsValue,
       SUM(Detail.Qty) AS TotalItems,
       MAX(CASE WHEN Pay.PaymentMethodId=1 THEN Pay.PaymentValue END) AS Cash,
       MAX(CASE WHEN Pay.PaymentMethodId=2 THEN Pay.PaymentValue END) AS Visa
FROM Transactions AS Trans JOIN 
     TransactionDetails AS Detail 
     ON Trans.TransactionId = Detail.TransactionId JOIN 
     Payments AS Pay 
     ON Trans.TransactionId = Pay.TransactionId
GROUP BY Trans.TransactionId;

编辑:您需要在aggregation之前输入join

 select TransactionId, 
        sum(case when IsNew = 1 then qty else 0 end) as NewItems,
        sum(case when IsNew = 1 then ItemPrice else 0 end) as NewItemsValue,
        sum(case when IsOriginal = 1 then Qty else 0 end) as OriginalItems,
        sum(case when IsOriginal = 1 then ItemPrice else 0 end) as OriginalItemsValue, count(*) as TotalItems, sum(PaymentValue) as paid
 from TransactionDetails AS Detail 
 group by TransactionId;

答案 1 :(得分:0)

我必须使用子查询:

SELECT
(SELECT SUM(Qty) FROM TransactionDetails AS DetailNew WHERE DetailNew.TransactionId=Trans.TransactionId AND IsNew =1) AS NewItems,
(SELECT SUM(ItemPrice*Qty) FROM TransactionDetails AS DetailNew WHERE DetailNew.TransactionId=Trans.TransactionId AND IsNew =1) AS NewItemsValue,
(SELECT SUM(Qty) FROM TransactionDetails AS DetailOriginal WHERE DetailOriginal.TransactionId=Trans.TransactionId AND IsOriginal =1) AS OriginalItems,
(SELECT SUM(ItemPrice*Qty) FROM TransactionDetails AS DetailOriginal WHERE DetailOriginal.TransactionId=Trans.TransactionId AND IsOriginal =1) AS OriginalItemsValue,
(SELECT SUM(ItemPrice*Qty) FROM TransactionDetails AS Detail WHERE Detail.TransactionId=Trans.TransactionId) AS ItemsValue,
(SELECT SUM(Qty) FROM TransactionDetails) AS TotalItems,
(SELECT SUM(PaymentValue) FROM Payments) AS Paid,
(SELECT SUM(PaymentValue) FROM Payments WHERE PaymentMethodId=2) AS Visa,
(SELECT SUM(PaymentValue) FROM Payments WHERE PaymentMethodId=1) AS Cash
FROM Transactions AS Trans