SQL中WHERE与HAVING用法
在查询数据库表时,需要对表中的记录进行筛选,SQL
提供了两个约束子句,即WHERE
与HAVING
,二者效果有雷同,但用法有区别。
语法区别
WHERE
1 | SELECT column_name FROM table_name WHERE column operator value |
HAVING
1 | SELECT column_name, aggregate_function(column_name) |
使用区别
WHERE
作用对象为数据库表、视图,HAVING
作用对象为于组(Group
);WHERE
在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算),而HAVING
在分组和聚集之后选取分组的行。因此,WHERE
子句不能包含聚集函数;因为试图用聚集函数判断那些行输入给聚集运算是没有意义的。相反,HAVING
子句总是包含聚集函数。(严格说来,你可以写不使用聚集的HAVING
子句, 但这样做只是白费劲。同样的条件可以更有效地用于WHERE
阶段。)
例子说明
WHERE实例
如果只希望选取居住在城市 “Beijing” 中的人,我们需要向SELECT
语句添加WHERE
子句:
1 | SELECT * FROM Persons WHERE City='Beijing' |
“Persons”表
LastName | FirstName | Address | City | Year |
---|---|---|---|---|
Adams | John | Oxford Street | London | 1970 |
Bush | George | Fifth Avenue | New York | 1975 |
Carter | Thomas | Changan Street | Beijing | 1980 |
Gates | Bill | Xuanwumen 10 | Beijing | 1985 |
结果:
LastName | FirstName | Address | City | Year |
---|---|---|---|---|
Carter | Thomas | Changan Street | Beijing | 1980 |
Gates | Bill | Xuanwumen 10 | Beijing | 1985 |
HAVING实例
我们拥有下面这个“Orders”表:
O_Id | OrderDate | OrderPrice | Customer |
---|---|---|---|
1 | 2008/12/29 | 1000 | Bush |
2 | 2008/11/23 | 1600 | Carter |
3 | 2008/10/05 | 700 | Bush |
4 | 2008/09/28 | 300 | Bush |
5 | 2008/08/06 | 2000 | Adams |
6 | 2008/07/21 | 100 | Carter |
现在,我们希望查找订单总金额少于 2000 的客户。
我们使用如下SQL
语句:
1 | SELECT Customer,SUM(OrderPrice) FROM Orders |
结果集类似:
Customer | SUM(OrderPrice) |
---|---|
Carter | 1700 |
WHERE与HAVING综合例子
接HAVING
中例子,现在我们希望查找客户 “Bush” 或 “Adams” 拥有超过 1500 的订单总金额。
我们在SQL
语句中增加了一个普通的WHERE
子句:
1 | SELECT Customer,SUM(OrderPrice) FROM Orders |
结果集:
Customer | SUM(OrderPrice) |
---|---|
Bush | 2000 |
Adams | 2000 |
结论
WHERE
子句用来筛选FROM
子句中指定的操作所产生的行。GROUP BY
子句用来分组WHERE
子句的输出。HAVING
子句用来从分组的结果中筛选行。
注
下面的运算符可在WHERE
子句中使用:
操作符 | 描述 |
---|---|
= | 等于 |
<> | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN | 在某个范围内 |
LIKE | 搜索某种模式 |
SQL
使用单引号来环绕文本值(大部分数据库系统也接受双引号)。如果是数值,请不要使用引号。
这是正确的:
1
SELECT * FROM Persons WHERE FirstName = 'Bush'
这是错误的:
1
SELECT * FROM Persons WHERE FirstName = Bush
这是正确的:
1
SELECT * FROM Persons WHERE Year > 1965
这是错误的:
1
SELECT * FROM Persons WHERE Year > '1965'