2010-07-01 68 views

回答

17

在你的例子中,他们应该做同样的事情。但WHERE得到处理之前任何GROUP BY,所以它不能访问聚合值(即,Min(),Max()等功能的结果)。 HAVING得到处理GROUP BY后,所以可以用来约束结果集只有那些聚合值匹配某个谓词。

+4

要以Daniel的答案的另一种方式,where子句适用于结果集中的所有行。 having子句应用于由group by子句创建的组。因此,如果您的组由您的示例中的column1组成,并且条件位于列1上,那么where与has相同,因为一行与“group”相同。 – Anon246 2010-07-01 17:04:40

+0

@Strommy:的确如此。如果由于某种原因你不想使用'HAVING',你可以通过使用嵌套的'SELECT'并使用外部的'WHERE'子句来表达你想要的谓词来完成同样的事情。 – 2010-07-01 18:59:13

3

不,因为是用于聚合函数或group by子句。

例如:

SELECT COUNT(ID) 
FROM tablexpto 
where name = 'a' 
having count(ID) > 1 

第一个查询将无法运行。

6

HAVING用于集合,例如,HAVING SUM(column1) > 200,WHERE仅用于列,例如WHERE column1 < 20

1

只能使用group by子句,并在分组后记录限制。

3

不,它们完全不同。

有条件用于分组聚合函数。计算汇总值后计算它们。

实施例:

select id, count(1) 
    from table 
where COND1 
having count(1) > 1 

这里,having部分后评价查询计算每个组的计数(1)值。

4

在您的例子,它是一样的,因为你没有GROUP BY

,否则具有之后 GROUP BY这后应用WHERE ...

话说应用,HAVING用一个简单的过滤器(x = 2)就是正好是与WHERE相同,因为x = 2只有在分组时才有意义。您通常对汇总(例如COUNT(*) > 2)使用HAVING,只能在GROUP BY后应用

-1

使用具有您by子句需要一个组。你会得到一个错误没有一个

+1

错误:如果在SELECT语句中使用了一个字面值(即没有列名),并省略了一个GROUP BY子句,则HAVING子句将应用于整个表(或过滤结果集,如果WHERE)子句使用'),如果'HAVING'子句被评估为TRUE,则返回任一行,否则返回零行。示例:查找数字序列中是否有空格:'SELECT 1 FROM HAVING MAX(num)= COUNT(*);' – onedaywhen 2010-07-01 21:55:43

+0

这是鬼鬼祟祟的,有人在现实世界中使用过这个吗?怎么样? – kacalapy 2010-07-02 16:47:12

3

正如其他人(大部分)正确地指出,在SQL的WHERE子句的SELECT子句前进行评估,因此一组函数的结果是“超出范围”的WHERE子句。

例如,你不能做到这一点:

SELECT Subject, MAX(Mark) AS TopScore 
    FROM Exam_Marks 
GROUP 
    BY Subject 
WHERE TopScore <= 70; 

,因为该列相关名TopScore不在范围内为WHERE条款。

当然,我们可以使用子查询:

SELECT DT1.TopScore 
    FROM (
     SELECT Subject, MAX(Mark) AS TopScore 
      FROM Exam_Marks 
     GROUP 
      BY Subject 
     ) AS DT1 
WHERE DT1.TopScore <= 70; 

的问题是,SQL的早期实现(从IBM的System R)缺乏支持派生表,因此直观HAVING诞生了。

你可以从Hugh Darwen那里看到HAVING A Blunderful Time (or Wish You Were WHERE)的完整遗憾故事,我借用了上面的例子。