SQL:HAVING子句

时间:2010-04-30 14:45:05

标签: sql ms-access having

请参阅以下SQL语句:

SELECT datediff("d", MAX(invoice.date), Now) As Date_Diff
      , MAX(invoice.date) AS max_invoice_date
      , customer.number AS customer_number
FROM invoice 
    INNER JOIN customer 
        ON invoice.customer_number = customer.number
GROUP BY customer.number 

如果添加了以下内容:

HAVING datediff("d", MAX(invoice.date), Now) > 365

这会简单地排除Date_Diff< = 365?

的行

这里的HAVING条款会有什么影响?

编辑:我没有体验到这里的答案。 mdb的副本位于http://hotfile.com/dl/40641614/2353dfc/test.mdb.html(没有宏或病毒)。 VISDATA.EXE用于执行查询。

EDIT2:我认为问题可能是VISDATA,因为我通过DAO遇到了不同的结果。

7 个答案:

答案 0 :(得分:5)

正如已经指出的那样,是的,就是效果。为了完整性,'HAVING'就像'WHERE',但是对于已经聚合的(分组的)值(例如,在这种情况下为MAX,或SUM,或COUNT,或任何其他聚合函数)。

答案 1 :(得分:1)

是的,它会排除这些行。

答案 2 :(得分:0)

是的,这就是它的功能。

答案 3 :(得分:0)

WHERE适用于所有单独的行,因此WHERE MAX(...)将匹配所有行。

HAVING就像WHERE,但在当前组中。这意味着你可以做像HAVING count(*)>这样的事情。 1,只显示具有多个结果的组。

所以要回答你的问题,它只会包含那些具有最高(MAX)日期的组中的记录大于365的行。在这种情况下,你也选择MAX(日期),所以是的,它排除了date_diff< = 365。

的行

但是,您可以选择MIN(日期)并查看最大日期大于365的所有组中的最小日期。在这种情况下,它不会排除date_diff< = 365的“行”,而是max(date_diff)< = 365。

的组

希望它不会太混乱......

答案 4 :(得分:0)

您可能正在使用MAX尝试错误的操作。通过MAXing invoice.date列,您可以有效地查找与客户关联的最新发票。因此,有效的HAVING条件是选择在过去365天内拥有任何发票的所有客户。

这是你想要做的吗?或者您是否真的试图让所有拥有一年多至少一张发票的客户?如果是这种情况,那么你应该将MAX放在datediff函数之外。

答案 5 :(得分:0)

这取决于您是表示表中的行还是结果中的行。 having子句在分组后过滤结果,因此它会消除客户,而不是发票。

如果您要过滤掉新发票而不是新发票的客户,则应使用where代替,以便在分组之前进行过滤:

select
  datediff("d",
  max(invoice.date), Now) As Date_Diff,
  max(invoice.date) as max_invoice_date,
  customer.number
from
  invoice 
  inner join customer on invoice.customer_number = customer.number
where
  datediff("d", invoice.date, Now) > 365
group by
  customer.number

答案 6 :(得分:0)

我根本不会使用GROUP BY查询。使用标准Jet SQL:

  SELECT Customer.Number
  FROM [SELECT DISTINCT Invoice.Customer_Number
     FROM Invoice
     WHERE (((Invoice.[Date])>Date()-365));]. AS Invoices 
  RIGHT JOIN Customer ON Invoices.Customer_Number = Customer.Number
  WHERE (((Invoices.Customer_Number) Is Null));

使用SQL92兼容模式:

  SELECT Customer.Number
  FROM (SELECT DISTINCT Invoice.Customer_Number
     FROM Invoice
     WHERE (((Invoice.[Date])>Date()-365));) AS Invoices 
  RIGHT JOIN Customer ON Invoices.Customer_Number = Customer.Number
  WHERE (((Invoices.Customer_Number) Is Null));

这里的关键是获取一组去年有发票的客户编号,然后对该结果集进行OUTER JOIN,以便仅返回那些没有发票的客户的客户编号。去年。