用谓词筛选数据
仅包含 SELECT 和 FROM 子句的最简单 SELECT 语句将计算表中的每一行。 通过使用 WHERE 子句,可以定义确定将处理哪些行并可能减少结果集的条件。
WHERE 子句的结构
WHERE 子句由一个或多个搜索条件组成,每个搜索条件对表中的每一行必须求值为 TRUE、FALSE 或“未知”。 仅当 WHERE 子句的计算结果为 TRUE 时,才会返回行。 各个条件充当数据的筛选器,称为“谓词”。 每个谓词包括一个正在测试的条件,通常使用基本比较运算符:
- =(等于)
- <>(不等于)
- >(大于)
- >=(大于或等于)
- <(小于)
- <=(小于或等于)
例如,以下查询返回 ProductCategoryID 值为 2 的所有产品:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2;
同样,以下查询返回 ListPrice 小于 10.00 的所有产品:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice < 10.00;
IS NULL / IS NOT NULL
还可以使用“IS NULL”或“IS NOT NULL”轻松筛选以允许或排除“未知”或 NULL 值。
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductName IS NOT NULL;
多个条件
多个谓词可以与 AND 和 OR 运算符以及括号结合使用。 但是 SQL Server 一次只处理两个条件。 使用 AND 运算符连接多个条件时,所有条件都必须为 TRUE。 使用 OR 运算符连接两个条件时,对于结果集,其中的一个或两个条件可以为 TRUE。
例如,下面的查询返回类别 2 中成本低于 10.00 的产品:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2
AND ListPrice < 10.00;
除非使用括号,否则先处理 OR 运算符,然后再处理 AND 运算符。 最佳做法是,在使用两个以上的谓词时使用括号。 以下查询将返回类别 2 或 3 中成本低于 10.00 的产品:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE (ProductCategoryID = 2 OR ProductCategoryID = 3)
AND (ListPrice < 10.00);
比较运算符
Transact-SQL 包括可帮助简化 WHERE 子句的比较运算符。
IN
对于使用 OR 连接的同一个列,IN 运算符是多个等式条件的快捷方法。 在查询中使用多个 OR 条件没有任何问题,如以下示例所示:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2
OR ProductCategoryID = 3
OR ProductCategoryID = 4;
但是,使用 IN 清晰简洁,而且查询的性能不会受到影响。
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID IN (2, 3, 4);
BETWEEN
BETWEEN 是另一个捷径,可用于筛选值的上限和下限,而不是通过 AND 运算符使用两个条件。 下面两个查询是等效的:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice >= 1.00
AND ListPrice <= 10.00;
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice BETWEEN 1.00 AND 10.00;
BETWEEN 运算符使用包含边界值。 结果中将包含价格为 1.00 或 10.00 的产品。 查询日期字段时,BETWEEN 也很有用。 例如,以下查询将包括 2012 年 1 月 1 日到 2012 年 12 月 31 日之间修改过的所有产品名称:
SELECT ProductName, ModifiedDate
FROM Production.Product
WHERE ModifiedDate BETWEEN '2012-01-01' AND '2012-12-31';
ProductName
ModifiedDate
山地自行车袜,M
2012-01-01 00:00:00.000
HL Mountain Frame - Silver, 42
2012-03-05 00:00:00.000
HL Mountain Frame - Silver, 38
2012-08-29 00:00:00.000
Mountain-100 Silver, 38
2012-12-31 00:00:00.000
但是,由于我们没有指定时间范围,因此不会返回 2012-12-31 00:00:00.000 之后的任何结果。 若要准确包含日期和时间,我们需要在谓词中包含时间:
SELECT ProductName, ListPrice, ModifiedDate
FROM Production.Product
WHERE ModifiedDate BETWEEN '2012-01-01 00:00:00.000' AND '2012-12-31 23:59:59.999';
仅按日期筛选时,基本的比较运算符也很准确,例如“大于”(>) 和“等于”(=):
SELECT ProductName, ListPrice, ModifiedDate
FROM Production.Product
WHERE ModifiedDate >= '2012-01-01'
AND ModifiedDate < '2013-01-01';
LIKE
最终比较运算符只能用于字符数据,并且允许使用通配符和正则表达式模式。 使用通配符,可以指定部分字符串。 例如,可以使用以下查询返回名称中包含单词“mountain”的所有产品:
SELECT Name, ListPrice
FROM SalesLT.Product
WHERE Name LIKE '%mountain%';
% 通配符表示 0 个或更多字符的任何字符串,因此结果包括名称中任意位置有单词“mountain”的产品,如下所示:
名称
ListPrice
山地自行车袜,M
9.50
Mountain Bike Socks, L
9.50
HL Mountain Frame - Silver, 42
1364.0
HL Mountain Frame - Black, 42
1349.60
HL Mountain Frame - Silver, 38
1364.50
Mountain-100 Silver, 38
3399.99
可以使用 _ 通配符来表示单个字符,如下所示:
SELECT ProductName, ListPrice
FROM SalesLT.Product
WHERE ProductName LIKE 'Mountain Bike Socks, _';
以下结果仅包括以“山地自行车袜子”开头的产品,以及后面的单个字符:
ProductName
ListPrice
山地自行车袜,M
9.50
Mountain Bike Socks, L
9.50
还可以定义要查找的复杂模式字符串。 例如,以下查询搜索了名称以“山地-”开头的产品,后跟:
- 0 到 9 之间的三个字符
- 1 个空格
- 任何字符串
- 一个逗号
- 1 个空格
- 介于 0 和 9 之间的两个字符
SELECT ProductName, ListPrice
FROM SalesLT.Product
WHERE ProductName LIKE 'Mountain-[0-9][0-9][0-9] %, [0-9][0-9]';
该查询的结果可能如下所示:
ProductName
ListPrice
Mountain-100 Silver, 38
3399.99
Mountain-100 Silver, 42
3399.99
Mountain-100 Black, 38
3399.99
Mountain-100 Black, 42
3399.99
Mountain-200 Silver, 38
2319.99
Mountain-200 Silver, 42
2319.99
Mountain-200 Black, 38
2319.99
Mountain-200 Black, 42
2319.99