开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜