簡體   English   中英

如何在GROUP BY的聚合SELECT中使用CASE WHEN THEN?

[英]How to use CASE WHEN THEN inside aggregated SELECT with GROUP BY?

我有一個匯總的GROUP BY查詢,在添加CASE語句之前,該查詢工作正常。 添加后,我得到此錯誤:

"Column 'gym.SalesDocumentItems.SalesDocumentItemStatusID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

這是查詢:

select 
    a.AccountID, 
    isnull(sum(sdi.TotalAmount),0) AS Amount,
    isnull(sum(sdi.TotalDiscountAmount),0) AS Discount,
    isnull(sum(sdi.TaxAmount),0) AS TaxAmount, 
    isnull(sum(sdi.TaxDiscountAmount),0) AS TaxDiscountAmount, 
    isnull(sum(sdi.AmountPaid),0) AS AmountPaid,
    isnull(a.CreditAmountAvailable,0) * -1 AS Credit,
    CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN
        isnull(sum(sdi.TotalAmount),0) - isnull(sum(sdi.TotalDiscountAmount),0) + isnull(sum(sdi.TaxAmount),0) - isnull(sum(sdi.TaxDiscountAmount),0) - isnull(sum(sdi.AmountPaid),0) - isnull(a.CreditAmountAvailable,0)
    ELSE
        -isnull(a.CreditAmountAvailable,0)
    END
    AS Balance,
    r.RunningBalanceTotal,
    isnull(sum(sdi.TotalAmount),0) - isnull(sum(sdi.TotalDiscountAmount),0) + isnull(sum(sdi.TaxAmount),0) - isnull(sum(sdi.TaxDiscountAmount),0) - isnull(sum(sdi.AmountPaid),0) - isnull(a.CreditAmountAvailable,0) - r.RunningBalanceTotal AS Difference,
    isnull(a.CreditAmountAvailable,0) AS AccountCredit
from gym.Account a
join gym.SalesDocument sd
on a.AccountID = sd.AccountID
join gym.SalesDocumentItems sdi
on sd.salesdocumentid = sdi.salesdocumentid
join RunningBalanceTotals r
on a.AccountID = r.AccountID
group by a.AccountID, a.CreditAmountAvailable, r.RunningBalanceTotal

我不確定如何實現這一目標。 我需要case語句,以便在不同情況下select的行為不同。 對於其中sdi.SalesDocumentItemStatusID IN(1,3)的任何記錄,我需要完整的計算; 否則,我只需要CreditAmountAvailable的負數即可。

我該如何實現? 我正在使用MS SQL Server 2012。

[[編輯]]

這是基於以下弗蘭克查詢的修改后的查詢:

WITH ungrouped as (
    SELECT a.AccountID, 
           sdi.TotalAmount,
           CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN 1 ELSE 2 END AS method,
           sdi.TaxAmount,
           sdi.TotalDiscountAmount,
           sdi.TaxDiscountAmount,
           sdi.AmountPaid,
           a.CreditAmountAvailable,
           r.RunningBalanceTotal
      from gym.Account a
      join gym.SalesDocument sd
      on a.AccountID = sd.AccountID
      join gym.SalesDocumentItems sdi
      on sd.salesdocumentid = sdi.salesdocumentid
      join RunningBalanceTotals r
      on a.AccountID = r.AccountID
)
SELECT ungrouped.AccountID, 
       CASE WHEN ungrouped.method = 1 THEN
            isnull(sum(ungrouped.TotalAmount),0) - isnull(sum(ungrouped.TotalDiscountAmount),0) + isnull(sum(ungrouped.TaxAmount),0) - isnull(sum(ungrouped.TaxDiscountAmount),0) - isnull(sum(ungrouped.AmountPaid),0) - isnull(ungrouped.CreditAmountAvailable,0)
       ELSE
            -isnull(ungrouped.CreditAmountAvailable,0)
       END AS Balance,
       ungrouped.RunningBalanceTotal,
       isnull(sum(ungrouped.TotalAmount),0) - isnull(sum(ungrouped.TotalDiscountAmount),0) + isnull(sum(ungrouped.TaxAmount),0) - isnull(sum(ungrouped.TaxDiscountAmount),0) - isnull(sum(ungrouped.AmountPaid),0) - isnull(ungrouped.CreditAmountAvailable,0) - ungrouped.RunningBalanceTotal AS Difference,
       isnull(ungrouped.CreditAmountAvailable,0) AS Credit
  FROM ungrouped
  where ungrouped.AccountID IN (    4238534,    4231337,    4132170, 4100923, 4137728, 4143255,     4230150, 4238565 
  )
GROUP BY ungrouped.AccountID, ungrouped.CreditAmountAvailable, ungrouped.RunningBalanceTotal, ungrouped.method
ORDER BY ungrouped.AccountID

首先獲取所有列,並包括CASE邏輯的第一部分,但不分組為CTE,我稱之為ungrouped 然后,進行分組並將CTE的CASE的結果包括在GROUP BY

    WITH ungrouped as (
    SELECT a.AccountID, 
           sdi.TotalAmount,
           CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN 1 ELSE 2 END AS method,
           sdi.TaxAmount,
           sdi.TotalDiscountAmount,
           sdi.TaxDiscountAmount,
           sdi.AmountPaid,
           a.CreditAmountAvailable,
           r.RunningBalanceTotal
      from gym.Account a
      join gym.SalesDocument sd
      on a.AccountID = sd.AccountID
      join gym.SalesDocumentItems sdi
      on sd.salesdocumentid = sdi.salesdocumentid
      join RunningBalanceTotals r
      on a.AccountID = r.AccountID
)
SELECT ungrouped.AccountID, 
       isnull(sum(ungrouped.TotalAmount),0) AS Amount,
       isnull(sum(ungrouped.TotalDiscountAmount),0) AS Discount,
       isnull(sum(ungrouped.TaxAmount),0) AS TaxAmount, 
       isnull(sum(ungrouped.TaxDiscountAmount),0) AS TaxDiscountAmount, 
       isnull(sum(ungrouped.AmountPaid),0) AS AmountPaid,
       isnull(ungrouped.CreditAmountAvailable,0) * -1 AS Credit,
       CASE WHEN ungrouped.method = 1 THEN
            isnull(sum(ungrouped.TotalAmount),0) - isnull(sum(ungrouped.TotalDiscountAmount),0) + isnull(sum(ungrouped.TaxAmount),0) - isnull(sum(ungrouped.TaxDiscountAmount),0) - isnull(sum(ungrouped.AmountPaid),0) - isnull(ungrouped.CreditAmountAvailable,0)
            ELSE
                -isnull(ungrouped.CreditAmountAvailable,0)
       END AS Balance,
       ungrouped.RunningBalanceTotal,
       isnull(sum(ungrouped.TotalAmount),0) - isnull(sum(ungrouped.TotalDiscountAmount),0) + isnull(sum(ungrouped.TaxAmount),0) - isnull(sum(ungrouped.TaxDiscountAmount),0) - isnull(sum(ungrouped.AmountPaid),0) - isnull(ungrouped.CreditAmountAvailable,0) - ungrouped.RunningBalanceTotal AS Difference,
       isnull(ungrouped.CreditAmountAvailable,0) AS AccountCredit
  FROM ungrouped
GROUP BY ungrouped.AccountID, ungrouped.CreditAmountAvailable, ungrouped.RunningBalanceTotal, ungrouped.method

查看對原始問題的評論,我發現要求是如果sdi.SalesDocumentItemStatusID與1或3不同,則在總和中使用零。這可以通過將CASE拖到總和中來處理:

select 
    a.AccountID, 
    isnull(sum(sdi.TotalAmount),0) AS Amount,
    isnull(sum(sdi.TotalDiscountAmount),0) AS Discount,
    isnull(sum(sdi.TaxAmount),0) AS TaxAmount, 
    isnull(sum(sdi.TaxDiscountAmount),0) AS TaxDiscountAmount, 
    isnull(sum(sdi.AmountPaid),0) AS AmountPaid,
    isnull(a.CreditAmountAvailable,0) * -1 AS Credit,

      isnull(sum(CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN sdi.TotalAmount ELSE 0 END),0)
    - isnull(sum(CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN sdi.TotalDiscountAmount ELSE 0 END),0)
    + isnull(sum(CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN sdi.TaxAmount ELSE 0 END),0)
    - isnull(sum(CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN sdi.TaxDiscountAmount ELSE 0 END),0)
    - isnull(sum(CASE WHEN sdi.SalesDocumentItemStatusID IN(1,3) THEN sdi.AmountPaid ELSE 0 END),0)
    - isnull(a.CreditAmountAvailable,0)
    AS Balance,

    r.RunningBalanceTotal,
    isnull(sum(sdi.TotalAmount),0) - isnull(sum(sdi.TotalDiscountAmount),0) + isnull(sum(sdi.TaxAmount),0) - isnull(sum(sdi.TaxDiscountAmount),0) - isnull(sum(sdi.AmountPaid),0) - isnull(a.CreditAmountAvailable,0) - r.RunningBalanceTotal AS Difference,
    isnull(a.CreditAmountAvailable,0) AS AccountCredit
from gym.Account a
join gym.SalesDocument sd
on a.AccountID = sd.AccountID
join gym.SalesDocumentItems sdi
on sd.salesdocumentid = sdi.salesdocumentid
join RunningBalanceTotals r
on a.AccountID = r.AccountID
group by a.AccountID, a.CreditAmountAvailable, r.RunningBalanceTotal

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM