繁体   English   中英

SQL:HAVING子句

[英]SQL: HAVING clause

请参阅以下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遇到了不同的结果。

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

是的,它会排除那些行。

是的,这就是它会做的。

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

HAVING就像WHERE,但在当前组内。 这意味着您可以执行HAVING count(*)> 1之类的操作,这只会显示具有多个结果的组。

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

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

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

你的MAX可能会做错了。 通过MAXing invoice.date列,您可以有效地查找与客户关联的最新发票。 因此,有效的HAVING条件是选择在过去365天内没有 任何发票的所有客户。

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

这取决于您是表示表中的行还是结果中的行。 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

我根本不会使用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,以便仅返回去年没有发票的客户组中的那些客户编号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM