在MySQL中使用HAVING过滤查询中的行

时间:2014-08-21 12:00:25

标签: mysql sql

HAVING通常与GROUP BY一起使用,但在我的查询中我需要它以便我可以过滤派生列

示例查询:

SELECT 
  id,
  NOW() < expiration_date 
  OR expiration_date IS NULL AS is_active 
FROM
  products 
HAVING is_active = 1 ;

我也可以使用临时表,只使用WHERE而不是HAVING,

示例:

SELECT id 
FROM
  (SELECT 
    id,
    NOW() < expiration_date 
    OR expiration_date IS NULL AS is_active 
  FROM
    products) 
WHERE is_active = 1 ;

无论哪种方式,我都能获得所需的结果,但即使您没有GROUP BY而且只是为了过滤派生行,它也非常适合使用HAVING。哪一个更好?

1 个答案:

答案 0 :(得分:1)

第二个查询更好。

顺便说一下,当您将结果限制为表达式时,您甚至可以将其缩短为:

SELECT 
  id,
  1 AS is_active 
FROM
  products
WHERE NOW() < expiration_date OR expiration_date IS NULL;

您的第一个查询不好。主要是因为它不是标准的SQL,因此可能会使其读者感到困惑。该查询在大多数其他dbms中无效。 HAVING用于汇总记录。

典型的事情是聚合和GROUP BY,然后使用HAVING过滤结果。省略GROUP BY通常会给你一条记录(如select max(col) from mytable)。在这种情况下,HAVING会过滤一个结果记录,因此您可以获得一个或没有结果记录。示例:select max(col) as maxc from mytable having maxc > 100)。

在MySQL中,您可以省略GROUP BY表达式。例如,select id, name from mytable group by id将为您提供id以及与该ID匹配的名称(并且由于每个ID通常有一个记录,因此您将获得该名称)。在另一个dbms中,您必须在名称上使用聚合函数,例如MIN或MAX,或者在GROUP BY子句中使用名称。在MySQL中你不必。省略它意味着:获取找到的(组)记录中的一个值。

所以你的第一个查询看起来有点像:将我的数据(因为你正在使用HAVING)聚合到一条记录(因为没有GROUP BY子句),所以你得到一条带有随机id的记录。这显然不是查询所做的,但说实话,我不能仅仅通过它看出来。我不是MySQL人,所以我不得不试着知道它是如何工作的,如果你没有告诉我们它是按照你的预期工作的。