SQL 查询聚合可能不会出现在 WHERE 子句中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7166626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SQL Query aggregate may not appear in WHERE clause
提问by Christopher Keeler
I have this SQL statement and SQL Server is giving me the following error:
我有这个 SQL 语句,SQL Server 给了我以下错误:
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list.
聚合可能不会出现在 WHERE 子句中,除非它位于包含在 HAVING 子句或选择列表中的子查询中。
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.
在 where 子句中,我只想提取最早未付帐单发票日期大于 DelinquentDaysThreshold(以天为单位)或 PastDueAmount(计算值)大于 DelinquentAmountThreshold 的记录。
出于某种原因,SQL Server 不喜欢聚合金额。
回答by gbn
Use the HAVING
as hinted by the error message, which requires a GROUP BY
:
使用HAVING
错误消息提示的,这需要一个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
回答by Matthew
Use "Having" for use with aggregate functions.
使用“Having”与聚合函数一起使用。
Heres a link: http://msdn.microsoft.com/en-us/library/ms180199.aspx
这是一个链接:http: //msdn.microsoft.com/en-us/library/ms180199.aspx
回答by James Johnson
In the where clause, I only want to pull records where the oldest unpaid Billing Invoice Date is greater than the DelinquentDaysThreshhold (in days)
在 where 子句中,我只想提取最早未付帐单发票日期大于 DelinquentDaysThreshhold(以天为单位)的记录
Some performance considerations with the HAVING clause:
HAVING 子句的一些性能注意事项:
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.
当您将 GROUP BY 与 HAVING 子句一起使用时,GROUP BY 子句将行划分为分组的行集并聚合它们的值,然后 HAVING 子句消除不需要的聚合组。在许多情况下,您可以编写 select 语句,使其仅包含 WHERE 和 GROUP BY 子句,而不包含 HAVING 子句。
As an alternative to the HAVING clause, you can also use derived tables to solve this problem:
作为 HAVING 子句的替代,你也可以使用派生表来解决这个问题:
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