3

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

4

7 回答 7

5

正如已经指出的那样,是的,这就是效果。为完整起见,“HAVING”类似于“WHERE”,但用于已经聚合(分组)的值(例如,本例中的 MAX,或 SUM,或 COUNT,或任何其他聚合函数)。

于 2010-04-30T14:53:43.497 回答
1

是的,它会排除这些行。

于 2010-04-30T14:46:10.957 回答
0

是的,这就是它会做的。

于 2010-04-30T14:47:36.057 回答
0

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

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

因此,要回答您的问题,它将仅包括组中具有最高 (MAX) 日期的记录大于 365 的行。在这种情况下,您还选择了 MAX(date),所以是的,它排除了具有 date_diff 的行<= 365。

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

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

于 2010-04-30T14:56:18.000 回答
0

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

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

于 2010-05-01T04:34:59.723 回答
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
于 2010-05-01T04:35:50.303 回答
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 以仅返回那些不在去年有发票的客户集中的客户编号。

于 2010-05-02T01:14:42.883 回答