我有一个聚合的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。
[[编辑]]
以下是基于Frank的查询的修改后的查询:
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
答案 0 :(得分:1)
首先获取所有列并包含CASE
逻辑的第一部分,但没有分组到CTE中,我称之为ungrouped
。然后,进行分组并在GROUP BY
中包含CTE的CASE结果:
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
答案 1 :(得分:0)
查看原始问题的评论,如果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