SQL Query aggregate may not appear in WHERE clause
I have this SQL statement and SQL Server is giving me the following error:
A开发者_如何学Gon aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list.
SELECT
SUM(M1.InvoiceTotal)-SUM(M1.AmountApplied) as PastDueAmount
, M1.BillingID
, M2.Name
, M2.DelinquentDaysThreshold
, M2.DelinquentAmountThreshold
, DATEDIFF(d, MIN(BillingDate),GETDATE()) as DaysLate
FROM Invoices M1
LEFT JOIN ClientAccounts M2 ON M1.BillingID = M2.ID
WHERE
InvoiceTotal <> AmountApplied
AND M2.DelinquentDaysThreshold > DATEDIFF(d, MIN(BillingDate),GETDATE())
OR (SUM(M1.InvoiceTotal)-SUM(M1.AmountApplied)) > M2.DelinquentAmountThreshold
GROUP BY
M1.BillingID
, M2.Name
, M2.DelinquentDaysThreshold
, M2.DelinquentAmountThreshold
In the where clause, I only want to pull records where the oldest unpaid Billing Invoice Date is greater than the DelinquentDaysThreshhold (in days), OR the PastDueAmount (a calculated value) is greater than the DelinquentAmountThreshold.
For some reason SQL Server does not like aggregated amounts.Use the HAVING
as hinted by the error message, which requires a GROUP BY
:
SELECT
SUM(M1.InvoiceTotal)-SUM(M1.AmountApplied) as PastDueAmount,
M1.BillingID, M2.Name,
M2.DelinquentDaysThreshold, M2.DelinquentAmountThreshold,
DATEDIFF(d, MIN(BillingDate),GETDATE()) as DaysLate
FROM
Invoices M1
LEFT JOIN
ClientAccounts M2 ON M1.BillingID = M2.ID
WHERE
InvoiceTotal <> AmountApplied
AND
M2.DelinquentDaysThreshold > DATEDIFF(d, MIN(BillingDate),GETDATE())
GROUP BY
M1.BillingID, M2.Name,
M2.DelinquentDaysThreshold, M2.DelinquentAmountThreshold,
DATEDIFF(d, MIN(BillingDate),GETDATE())
HAVING
(SUM(M1.InvoiceTotal)-SUM(M1.AmountApplied)) > M2.DelinquentAmountThreshold
Use "Having" for use with aggregate functions.
Heres a link: http://msdn.microsoft.com/en-us/library/ms180199.aspx
In the where clause, I only want to pull records where the oldest unpaid Billing Invoice Date is greater than the DelinquentDaysThreshhold (in days)
Some performance considerations with the HAVING clause:
When you use GROUP BY with the HAVING clause, the GROUP BY clause divides the rows into sets of grouped rows and aggregates their values, andthen the HAVING clause eliminates undesired aggregated groups. In many cases,you can write your select statement so it will contain only WHERE and GROUP BY clauses without a HAVING clause.
As an alternative to the HAVING clause, you can also use derived tables to solve this problem:
SELECT t1.SomeID, t1.SomeThreshold, totals.NumericTotal
FROM Table1 t1
INNER JOIN (
SELECT SomeID, SUM(SomeNumericValue) NumericTotal
FROM Table1
Group By SomeID
) totals
ON t1.SomeID = totals.SomeID
WHERE totals.NumericTotal > t1.SomeThreshold
精彩评论