3.6 SQL Server 查询数据
SQL是一种特殊目的的编程语言,它是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。SQL语句无论是种类还是数量都是繁多的,很多语句也是经常要用到的,SQL查询语句就是一个典型的例子,无论是高级查询还是低级查询,SQL查询语句的需求是最频繁的。
>[danger] ## 3.6.1 [SELECT]- 演示如何针对单个表查询数据。
数据库表是存储数据库中所有数据的对象。 在表中,数据按行和列格式逻辑组织,类似于电子表格(Excel)。
在表中,每行代表一个唯一记录,每列代表记录中的一个字段。 例如,`customers`表包含客户数据,如客户标识号,名字,姓氏,电话,电子邮件和地址信息,如下所示:
![](https://www.yiibai.com/uploads/article/2019/02/14/150408_29814.png)
SQL Server使用模式对表和其他数据库对象进行逻辑分组。 在示例数据库(`bb_stores`)中,有两个模式:`sales`和`production`。 `sales`模式将所有与销售相关的表分组,而`production`模式将所有与生产相关的表分组。
要从表中查询数据,请使用`SELECT`语句。 以下是`SELECT`语句的最基本形式:
~~~sql
SELECT
select_list
FROM
schema_name.table_name;
~~~
在上面语法中,
* 首先,`select_list`指定要在`SELECT`子句中查询数据的逗号分隔列的列表。
* 其次,`schema_name.table_name`是在`FROM`子句中指定源表及其模式名称。
处理SELECT语句时,SQL Server首先处理`FROM`子句,然后处理`SELECT`子句,即使SELECT子句首先出现在查询中也是一样。
## SQL Server SELECT语句示例
下面将使用示例数据库中的`customers`表进行演示。
![](https://www.yiibai.com/uploads/article/2019/02/14/151034_47806.png)
#### 1\. SQL Server SELECT检索表部分列示例
以下查询查找所有客户的名字和姓氏:
~~~sql
SELECT
first_name,
last_name
FROM
sales.customers;
~~~
执行上面查询语句,得到以下结果 -
![](https://www.yiibai.com/uploads/article/2019/02/14/151205_93029.png)
查询的结果称为**结果集**。
以下语句返回所有客户的名字,姓氏和电子邮件:
~~~sql
SELECT
first_name,
last_name,
email
FROM
sales.customers;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/ea/03/ea03a507c178ebc55d620beb4e734ea2_644x499.png)
#### 2\. SQL Server SELECT从表中检索所有列的示例
要从表的所有列获取数据,可以指定选择列表中的所有列。 还可以使用`SELECT *`作为速记来减少一些书写:
~~~sql
SELECT
*
FROM
sales.customers;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/5c/a4/5ca4fa32e5ee092f2d373d76d89f056f_646x500.png)
`SELECT *`对于检查不熟悉表的列和数据非常有用,它对即席查询也很有帮助。
但是,由于以下主要原因,不应将`SELECT *`用于实际生产代码:
* 首先,`SELECT *`经常检索比应用程序需要运行的数据更多的数据。它会导致不必要的数据从SQL Server传输到客户端应用程序,从而花费更多时间使数据通过网络传输并减慢应用程序的速度。
* 其次,如果为表添加了一个或多个新列,则`SELECT *`只检索包含新添加的列的所有列,这些列不打算在应用程序中使用,这可能会导致应用程序崩溃。
#### 3\. SQL Server SELECT - 对结果集进行排序
要根据一个或多个条件筛选行,请使用`WHERE`子句。在此示例中,查询返回位于`CA`的客户。如以下示例所示:
~~~sql
SELECT
*
FROM
sales.customers
WHERE
state = 'CA';
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/f0/7b/f07bf59bde14a725a0b1385a5b6834c5_713x476.png)
当WHERE子句可用时,SQL Server按以下顺序处理查询的子句:`FROM`,`WHERE`和`SELECT`。要基于一个或多个列对结果集进行排序,请使用`ORDER BY`子句,如以下示例所示:
~~~sql
SELECT
*
FROM
sales.customers
WHERE
state = 'CA'
ORDER BY
first_name;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/8f/9a/8f9ab0344003376ad03b0101bdcbc8df_719x499.png)
在此示例中,`ORDER BY`子句按名字按升序对客户进行排序。在这种情况下,SQL Server按以下顺序处理查询的子句:`FROM`,`WHERE`,`SELECT`和`ORDER BY`。
#### 4\. SQL Server SELECT - 将行分组为组示例
要将行分组,请使用`GROUP BY`子句。 例如,以下语句将返回位于`CA`的所有客户以及每个城市的客户数量。参考以下查询语句:
~~~sql
SELECT
city,
COUNT (*)
FROM
sales.customers
WHERE
state = 'CA'
GROUP BY
city
ORDER BY
city;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/68/19/681913b16d7b81acebbb7bba54263757_721x503.png)
在这种情况下,SQL Server按以下顺序处理子句:`FROM`,`WHERE`,`GROUP BY`,`SELECT`和`ORDER BY`。
#### 5\. SQL Server SELECT - 过滤分组示例
要根据一个或多个条件筛选组,请使用`HAVING`子句。以下示例返回`CA`州拥有10个以上客户的城市:
~~~sql
SELECT
city,
COUNT (*)
FROM
sales.customers
WHERE
state = 'CA'
GROUP BY
city
HAVING
COUNT (*) > 10
ORDER BY
city;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/82/1d/821db0e487b0fb9c6a61bbc5db47bdc2_720x419.png)
请注意,`WHERE`子句在`HAVING`子句筛选器分组时筛选行。
>[danger] ## 3.6.2 [ORDER BY] - 根据指定列列表中的值对结果集进行排序
## SQL Server ORDER BY子句简介
使用`SELECT`语句从表中查询数据时,不保证结果集中的行顺序。 这意味着SQL Server可以返回具有未指定行顺序的结果集。
保证结果集中的行已排序的方法是使用`ORER BY`子句。 以下是`ORDER BY`子句的语法:
~~~sql
SELECT
select_list
FROM
table_name
ORDER BY
[column_name | expression] [ASC | DESC ]
~~~
在上面语法中,
* `column_name | expression` - 指定要对查询结果集进行排序的列名或表达式。 如果指定多个列,则结果集按第一列排序,然后该排序结果集按第二列排序,依此类推。`ORDER BY`子句中出现的列必须对应于选择列表中的列或`FROM`子句中指定的表中定义的列。
* `ASC | DESC` - 使用`ASC`或`DESC`指定是否应按升序或降序对指定列中的值进行排序。`ASC`将结果从最低值排序到最高值,而`DESC`将结果集从最高值排序到最低值。如果未明确指定`ASC`或`DESC`,则SQL Server将默认使用`ASC`来排序顺序。 此外,SQL Server将`NULL`视为最低值。
处理具有`ORDER BY`子句的`SELECT`语句时,`ORDER BY`子句是要处理的最后一个子句。
## SQL Server ORDER BY子句示例
将使用[示例数据库](http://www.yiibai.com/sqlserver/sql-server-sample-database.html "示例数据库")中的`customers`表进行演示。
![](https://www.yiibai.com/uploads/article/2019/02/14/165752_68792.png)
#### 1\. 按升序对结果集进行排序
以下语句按名字按升序对客户列表进行排序:
~~~sql
SELECT
first_name,
last_name
FROM
sales.customers
ORDER BY
first_name;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/90/b4/90b4b3d6afb233af1a67df84993dbcf4_722x425.png)
在此示例中,由于未指定`ASC`或`DESC`,`ORDER BY`子句默认使用`ASC`。
#### 2\. 按降序对结果集按一列排序
以下语句按名字降序对客户列表进行排序。
~~~sql
SELECT
firstname,
lastname
FROM
sales.customers
ORDER BY
first_name DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://www.yiibai.com/uploads/article/2019/02/14/170152_99779.png)
在此示例中,因为显式指定了`DESC`,所以`ORDER BY`子句按降序对`first_name`列中的值对结果集进行降序排序。
#### 3\. 按多列对结果集进行排序
以下语句检索客户的名字,姓氏和城市。 它首先按城市对客户列表进行排序,然后按名字排序。
~~~sql
SELECT
city,
first_name,
last_name
FROM
sales.customers
ORDER BY
city,
first_name;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/b6/f9/b6f98fb679def13e9c2116e5e8efe57f_721x422.png)
#### 4\. 按多列和不同顺序对结果集进行排序
以下语句按城市按降序对客户进行排序,之后按第一个名称按升序对排序结果进行排序。
~~~sql
SELECT
city,
first_name,
last_name
FROM
sales.customers
ORDER BY
city DESC,
first_name ASC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/65/f7/65f75f2faadc5daec8cfb9a6cad793a0_715x417.png)
#### 5\. 按不在选择列表中的列对结果集进行排序
可以通过选择列表中未显示的列对结果集进行排序。 例如,以下语句按`state`对客户进行排序,即使`state`列未显示在选择列表中。
~~~sql
SELECT
city,
first_name,
last_name
FROM
sales.customers
ORDER BY
state;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/5c/c1/5cc16c41b9561a8ea7f9cd710b8cd065_722x419.png)
请注意,`state`列在`customers`表中定义。 如果不是,那么查询将无效。
#### 6\. 按表达式对结果集进行排序
`LEN()`函数返回字符串的字符数。 以下语句使用`ORDER BY`子句中的`LEN()`函数来检索按名字长度排序客户列表。
~~~sql
SELECT
first_name,
last_name,
LEN(first_name) as len_name
FROM
sales.customers
ORDER BY
LEN(first_name) DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/1a/2f/1a2fb0cec03645c6e935621f30cb17fc_723x418.png)
#### 7\. 按列的序数位置排序
SQL Server允许根据选择列表中显示的列的序号位置对结果集进行排序。
以下语句按名字和姓氏对客户进行排序。 但是它没有显式指定列名,而是使用列的序号位置:
~~~sql
SELECT
first_name,
last_name
FROM
sales.customers
ORDER BY
1,
2;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/24/9c/249c4c21f40122859a63d134e64cd477_718x418.png)
在此示例中,`1`表示`first_name`列,`2`表示`last_name`列。
由于几个原因,在`ORDER BY`子句中使用列的序号位置是不推荐使用的。
* 首先,表中的列没有序号位置,需要按名称引用。
* 其次,当修改选择列表时,可能忘记在`ORDER BY`子句中进行相应的更改。
因此,最好始终在`ORDER BY`子句中显式指定列名。
>[danger] ## 3.6.3 [OFFSET FETCH] - 演示如何限制查询返回的行数。
在本教程中,将学习如何使用SQL Server `OFFSET FETCH`子句来限制查询返回的行数。
`OFFSET`和`FETCH`子句是`ORDER BY`子句的选项。 它们用于限制查询返回的行数。
以下是`OFFSET`和`FETCH`子句的语法:
~~~sql
ORDER BY column_list [ASC |DESC]
OFFSET offset_row_count {ROW | ROWS}
FETCH {FIRST | NEXT} fetch_row_count {ROW | ROWS} ONLY
~~~
在上面语法中,
* `OFFSET`子句指定在开始从查询返回行之前要跳过的行数。`offset_row_count`可以是大于或等于零的常量,变量或参数。
* `FETCH`子句指定在处理`OFFSET`子句后要返回的行数。 `offset_row_count`可以是大于或等于`1`的常量,变量或标量。
* `OFFSET`子句是必需的,而`FETCH`子句是可选的。 此外,`FIRST`和`NEXT`是同义词,因此可以互换使用它们。
以下图中说明了`OFFSET`和`FETCH`子句:
![](https://www.yiibai.com/uploads/article/2019/02/14/194633_39959.png)
请注意,必须将`OFFSET`和`FETCH`子句与`ORDER BY`子句一起使用。 否则将收到错误消息。
`OFFSET`和`FETCH`子句比实现`TOP`子句更适合实现查询分页解决方案。
## SQL Server OFFSET和FETCH示例
下面将使用示例数据库中的`products`表进行演示。
![](https://www.yiibai.com/uploads/article/2019/02/16/123303_42112.png)
以下查询返回`products`表中的所有产品,并按其价格和名称对产品进行排序:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name;
~~~
执行上面示例查询语句,得到以下结果 -
![](https://img.kancloud.cn/c3/09/c30945ab12ba481ea2eb40edfaaa86e6_640x463.png)
要跳过前`10`个产品并返回其余产品,请使用`OFFSET`子句,如以下语句所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name
OFFSET 10 ROWS;
~~~
执行上面示例查询语句,得到以下结果 -
![](https://img.kancloud.cn/e4/8b/e48bd00fe72ae5221ed1c6d10703686a_644x490.png)
要跳过前`10`个产品并选择接下来的`10`个产品,请使用`OFFSET`和`FETCH`子句,如下所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
~~~
执行上面示例查询语句,得到以下结果 -
![](https://img.kancloud.cn/a9/f2/a9f205a5e716c174b1ab841ecba03b50_641x532.png)
要获得前`10`个最贵的产品,请使用`OFFSET`和`FETCH`子句,如下所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC,
product_name
OFFSET 0 ROWS
FETCH FIRST 10 ROWS ONLY;
~~~
执行上面示例查询语句,得到以下结果 -
![](https://img.kancloud.cn/98/e0/98e01157bf19b311e30509209bb6bf42_642x533.png)
在此示例中,`ORDER BY`子句按价格按降序对产品进行排序。 然后,`OFFSET`子句跳过零行,`FETCH`子句从列表中获取前`10`个产品。
>[danger] ## 3.6.4 [SELECT TOP] - 演示如何限制查询结果集中返回的行数或行百分比。
在本教程中,将学习如何使用SQL Server `SELECT TOP`语句来限制查询返回的行。
SELECT `TOP`子句用于限制查询结果集中返回的行数或行百分比。
由于存储在表中的行的顺序是不可预测的,因此`SELECT TOP`语句始终与`ORDER BY`子句一起使用。 结果,结果集限于前`N`个有序行数。
以下是带有`SELECT`语句的`TOP`子句的语法:
~~~sql
SELECT TOP (expression) [PERCENT]
[WITH TIES]
FROM
table_name
ORDER BY
column_name;
~~~
在此语法中,`SELECT`语句可以包含其他子句,如:`WHERE`,`JOIN`,`HAVING`和`GROUP BY`。
* `expression` - `TOP`关键字后面是一个表达式,它指定要返回的行数。 如果使用`PERCENT`,则将表达式计算为浮点值,否则将其转换为`BIGINT`值。
* `PERCENT` - `PERCENT`关键字指示查询返回前`N`个行百分比,其中`N`是表达式的结果。
* `WITH TIES` - `WITH TIES`用于返回更多行,其值与有限结果集中的最后一行匹配。 请注意,`WITH TIES`可能会导致返回的行数多于在表达式中指定的行数。
例如,如果要返回表达式最多的产品,可以使用`TOP 1`。但是,如果两个或更多产品的价格与最贵的产品相同,那么会错过结果集中其他最贵的产品。 为避免这种情况,可以使用`TOP 1 WITH TIES`。 它不仅包括第一个最贵的产品,还包括第二个,第三个,等等。
#### SQL Server SELECT TOP示例
下面将使用[示例数据库]中的`production.products`表进行演示。
#### 1\. 使用具有恒定值的TOP
以下示例使用常量值返回前`10`个最贵的产品。
~~~sql
SELECT TOP 10
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/1f/4b/1f4bf5d2f52901ee3882f2721e2641be_637x528.png)
#### 2\. 使用TOP返回行的百分比
以下示例使用`PERCENT`指定结果集中返回的产品数。 `production.products`表有`321`行,因此,`321`的百分之一是分数值(`3.21`),SQL Server将其四舍五入到下一个整数,在这种情况下是`4`行记录。
~~~sql
SELECT TOP 1 PERCENT
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/9e/b4/9eb415e7bb2075d8a8d4e2b3d4435eea_636x530.png)
#### 3\. 使用TOP WITH TIES包含与最后一行中的值匹配的行
以下声明返回了最贵的前三个产品:
~~~sql
SELECT TOP 3 WITH TIES
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/e7/b7/e7b79c636125677d41d0d342f271be81_640x440.png)
在此示例中,第三个最贵的产品的定价为`6499.99`。 由于语句中使用`TOP WITH TIES`,因此它返回了另外价格与第三个相同的三个产品。
>[danger] # 过滤数据部分
>[danger] ## 1:) [DISTINCT] - 在表的一列或多列中选择不同的值(消除相同的值)。
有时,可能希望仅在表的指定列中获取不同的值。那么请使用`SELECT DISTINCT`子句,如下所示:
~~~sql
SELECT DISTINCT
column_name
FROM
table_name;
~~~
查询仅返回指定列中的不同值。 换句话说,它从结果集中删除列中的重复值。
如果使用多列,语法如下所示:
~~~sql
SELECT DISTINCT
column_name1,
column_name2 ,
...
FROM
table_name;
~~~
该查询使用`SELECT`列表中所有指定列中的值组合来评估唯一性。
如果将`DISTINCT`子句应用于具有`NULL`值的列,则`DISTINCT`子句将仅保留一个`NULL`并消除其它的`NULL`值。 换句话说,`DISTINCT`子句将所有`NULL`值视为相同的值。
## SQL Server SELECT DISTINCT示例
为了方便演示,将使用示例数据库中的`customers`表。表的结构如下所示:
![](https://www.yiibai.com/uploads/article/2019/02/17/110429_58643.png)
#### A. DISTINCT一个字段的示例
以下语句返回`customers`表中所有客户所在的所有城市:
~~~sql
SELECT
city
FROM
sales.customers
ORDER BY
city;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/51/c2/51c2c6994fd81629cb033c84e68d7e44_637x437.png)
从查询输出中可以清楚地看到,城市是重复的。
要获取不同的城市唯一值,请按如下方式添加`DISTINCT`关键字:
~~~sql
SELECT DISTINCT
city
FROM
sales.customers
ORDER BY
city;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/3d/2d/3d2d9a08cfbe299f323d51d92898f02f_639x437.png)
现在,查询为每组重复项返回一个不同的值。也就是说它从结果集中删除了所有重复的城市。
#### B. DISTINCT多列示例
以下语句查找所有客户的不同城市和州。
~~~sql
SELECT DISTINCT
city,
state
FROM
sales.customers
~~~
执行以下查询语句,得到以下结果 -
![](https://img.kancloud.cn/69/e3/69e34bb03a20208cefbddfa31f4c71f3_636x437.png)
在此示例中,语句使用`city`和`state`列中的值组合来评估重复项。
#### C. DISTINCT带有null值示例
以下示例查找客户的不同(唯一)电话号码:
~~~sql
SELECT DISTINCT
phone
FROM
sales.customers
ORDER BY
phone;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/f9/ea/f9eaf906d7137d97628183cfda91fff8_638x438.png)
在此示例中,使用`DISTINCT`子句在`phone`列上,结果中删除其他`NULL`仅保留一个`NULL`值。
>[danger] ## 2:) [WHERE] - 根据一个或多个条件过滤查询输出中的行
当使用`SELECT`语句查询表中的数据时,将获得表的所有行,这是显然是不必要的,因为应用程序当时只能处理一组行。
要从表中获取满足一行或多个条件的行,请使用`WHERE`子句,如下所示:
~~~sql
SELECT
select_list
FROM
table_name
WHERE
search_condition;
~~~
在`WHERE`子句中,指定搜索条件以过滤`FROM`子句返回的行。 `WHERE`子句仅返回导致搜索条件计算为`TRUE`的行。
搜索条件是逻辑表达式或多个逻辑表达式的组合。 在SQL中,逻辑表达式通常称为谓词。
请注意,SQL Server使用三值谓词逻辑,其中逻辑表达式可以计算为`TRUE`,`FALSE`或`UNKNOWN`。 `WHERE`子句不会返回导致谓词计算结果为`FALSE`或`UNKNOWN`的任何行。
## SQL Server WHERE示例
我们将使用[示例数据库]中的`products`表进行演示,表的结构如下:
![](https://www.yiibai.com/uploads/article/2019/02/17/212629_63233.png)
#### A. 通过使用简单的相等来查找行
以下语句检索类别为`id`为`1`的所有产品:
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
category_id = 1
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/52/a7/52a74b082c585fb18a007562080b95e5_1389x712.png)
#### B. 查找满足两个条件的行
以下示例返回满足两个条件的产品:`category_id`为`1`,`model_year`为`2018`。它使用逻辑运算符`AND`来组合这两个条件。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
category_id = 1 AND model_year = 2018
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/13/be/13be5478a2ca86a56063f01c7f854c5c_1370x708.png)
#### C. 使用比较运算符查找行
以下语句查找价格大于`300`且型号为`2018`的产品。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price > 300 AND model_year = 2018
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/23/95/2395cb54ee8340295e6a5f19df56b068_1389x712.png)
#### D. 查找满足两个条件中的任何一个的行
以下查询查找价格大于`3000`或型号为`2018`的产品。满足其中一个条件的任何产品都包含在结果集中。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price > 3000 OR model_year = 2018
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/1d/73/1d7364193ba4fe42328e1d645be5af44_1381x712.png)
请注意,OR运算符用于组合谓词。
#### E. 查找具有两个值之间的值的行
以下语句查找价格介于`1899`和`1999.99`之间的产品:
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price BETWEEN 1899.00 AND 1999.99
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/7d/a6/7da63f5ce952fdca8ec4b53820c51be2_1384x715.png)
#### F. 查找值列表中具有值的行
以下示例使用`IN`运算符查找价格为`299.99`或`466.99`或`489.99`的产品。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price IN (299.99, 369.99, 489.99)
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/7a/26/7a26dd674f21d128932a887ae19520e4_1386x715.png)
#### G. 查找其值包含字符串的行
以下示例使用`LIKE`运算符查找名称中包含字符串`Cruiser`的产品:
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
product_name LIKE '%Cruiser%'
ORDER BY
list_price;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/01/40/01404641ea54e218bbe4234c9c7297a0_1392x741.png)
>[danger] ## 3:) [AND] - 组合两个布尔表达式,如果所有表达式都为真,则返回`true`。
在本教程中,将学习如何使用SQL Server `AND`运算符组合多个布尔表达式。
`AND`是一个逻辑运算符,用于组合两个布尔表达式。仅当两个表达式求值为`TRUE`时,它才返回`TRUE`。
以下说明了`AND`运算符的语法:
~~~sql
boolean_expression AND boolean_expression
~~~
`boolean_expression`是任何有效的布尔表达式,其计算结果为`TRUE`,`FALSE`和`UNKNOWN`。
## SQL Server AND运算符示例
我们将使用[示例数据库]中的`products`表进行演示,表的结构如下:
![](https://www.yiibai.com/uploads/article/2019/02/17/212629_63233.png)
#### A. 使用AND运算符示例
以下示例查找类别标识号(`category_id`)为`1`且价格大于`400`的产品:
~~~sql
SELECT
*
FROM
production.products
WHERE
category_id = 1
AND list_price > 400
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/d4/94/d494c31e2b49c2ffc8cfa662c159bc8d_639x528.png)
#### B. 使用多个AND运算符示例
以下语句查找满足以下所有条件的产品:类别编号(`category_id`)为`1`,价格大于`400`,品牌编号(`brand_id`)为`1`:
~~~sql
SELECT
*
FROM
production.products
WHERE
category_id = 1
AND list_price > 400
AND brand_id = 1
ORDER BY
list_price DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/b6/25/b62542d7ccce1d45e067505347669fda_643x532.png)
#### C. 使用AND与其他逻辑运算符
请参阅以下查询示例:
~~~sql
SELECT
*
FROM
production.products
WHERE
brand_id = 1
OR brand_id = 2
AND list_price > 1000
ORDER BY
brand_id DESC;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/dd/64/dd646062c11083444db4bb42c0d954c8_1368x707.png)
在这个例子中,在条件中使用了`OR`和`AND`运算符。与往常一样,SQL Server首先评估`AND`运算符。因此,查询检索到品牌编号为`2`且价格大于`1000`的产品或品牌编号为`1`的产品。
要获得品牌编号为`1`或`2`且价格大于`1000`的产品,请使用括号,如下所示:
~~~sql
SELECT
*
FROM
production.products
WHERE
(brand_id = 1 OR brand_id = 2)
AND list_price > 1000
ORDER BY
brand_id;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/d6/3a/d63acfe667bf00a76f9c5c7b80fc4b56_1372x713.png)
>[danger] ## 4:) [OR]- 组合两个布尔表达式,如果其中一个条件为真,则返回`true`
SQL Server `OR`是一个逻辑运算符,用于组合两个布尔表达式。当任一条件的计算结果为`TRUE`时,它返回`TRUE`。
以下显示了`OR`运算符的语法:
~~~sql
boolean_expression OR boolean_expression
~~~
在此语法中,`boolean_expression`是任何有效的布尔表达式,其计算结果为:`true`,`false`和`unknown`。
在语句中使用多个逻辑运算符时,SQL Server将在`AND`运算符之后计算`OR`运算符。 但是,可以使用括号更改评估顺序。
## SQL Server OR运算符示例
我们将使用[示例数据库]中的`products`表进行演示,表的结构如下:
![](https://www.yiibai.com/uploads/article/2019/02/17/212629_63233.png)
#### A. 使用OR运算符示例
以下示例查找价格小于`200`或大于`6000`的产品:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price < 200
OR list_price > 6000
ORDER BY
list_price;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/eb/bf/ebbf88dbc68e65826e2be1a7ef48142d_1383x712.png)
#### B. 使用多个OR运算符示例
以下语句查找品牌编号(`brand_id`)为`1`,`2`或`4`的产品:
~~~sql
SELECT
product_name,
brand_id
FROM
production.products
WHERE
brand_id = 1
OR brand_id = 2
OR brand_id = 4
ORDER BY
brand_id DESC;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/ed/11/ed1117f9d249b1cf9863fc3504578b3d_1383x707.png)
可以通过[IN运算符]替换多个`OR`运算符,如以下查询所示:
~~~sql
SELECT
product_name,
brand_id
FROM
production.products
WHERE
brand_id IN (1, 2, 3)
ORDER BY
brand_id DESC;
~~~
#### C. 使用OR和AND运算符示例
请考虑以下示例:
~~~sql
SELECT
product_name,
brand_id,
list_price
FROM
production.products
WHERE
brand_id = 3
OR brand_id = 4
AND list_price > 100
ORDER BY
brand_id DESC;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/df/6d/df6dfcdbc65568ffa33ee93bfb4c813f_1384x710.png)
在这个例子中,使用了`OR`和`AND`运算符。 与往常一样,SQL Server首先评估`AND`运算符。 因此,查询返回品牌编号(`brand_id`)为`4`且价格大于`100`的产品或品牌编号(`brand_id`)为`3`的产品。
要查找品牌编号(`brand_id`)为`3`或`4`且价格大于`100`的产品,请使用括号,如以下查询所示:
~~~sql
SELECT
product_name,
brand_id,
list_price
FROM
production.products
WHERE
(brand_id = 3 OR brand_id = 4)
AND list_price > 100
ORDER BY
brand_id;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/e0/85/e085fd2b4e124689313a42a8cf2aa65b_1386x713.png)
>[danger] ## 5:) [IN]- 检查值是否与列表或子查询中的任何值匹配。
`IN`运算符是一个逻辑运算符,用于测试指定的值是否与列表中的任何值匹配。
以下显示了SQL Server `IN`运算符的语法:
~~~sql
column | expression IN ( v1, v2, v3, ...)
~~~
在上面语法中,
* 首先,`column | expression`指定要测试的列或表达式。
* 其次,指定要测试的值列表。所有值必须与列或表达式的类型具有相同的类型。
如果列或表达式中的值等于列表中的任何值,则`IN`运算符的结果为`TRUE`。
`IN`运算符等效于多个`OR`运算符,因此,以下谓词是等效的:
~~~sql
column IN (v1, v2, v3)
column = v1 OR column = v2 OR column = v3
~~~
要取消`IN`运算符,请使用`NOT IN`运算符,如下所示:
~~~sql
column | expression NOT IN ( v1, v2, v3, ...)
~~~
如果列或表达式不等于列表中的任何值,则`NOT IN`运算符的结果为`TRUE`。
除了值列表之外,还可以使用子查询返回带有`IN`运算符的值列表,如下所示:
~~~sql
column | expression IN (subquery)
~~~
在此语法中,子查询是一个`SELECT`语句,它返回单个列的值列表。请注意,如果列表包含`NULL`,则`IN`或`NOT IN`的结果将为`UNKNOWN`。
## SQL Server OR运算符示例
我们将使用[示例数据库]中的`products`表进行演示,表的结构如下:
![](https://www.yiibai.com/uploads/article/2019/02/17/212629_63233.png)
#### A. SQL Server IN带有值列表示例
以下语句查找价格为以下值之一的产品:`89.99`,`109.99`和`159.99`:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price IN (89.99, 109.99, 159.99)
ORDER BY
list_price;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/30/14/301491e49c5e0ba030c121c772d4d1af_1384x712.png)
上面的查询等效于以下使用`OR`运算符的查询:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price = 89.99 OR list_price = 109.99 OR list_price = 159.99
ORDER BY
list_price;
~~~
要查找价格不是上述价格的产品,请使用`NOT IN`运算符,如以下查询中所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price NOT IN (89.99, 109.99, 159.99)
ORDER BY
list_price;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/a7/05/a70549e1f6f1115dd308e165a68e5e43_1369x711.png)
#### B. SQL Server IN带有子查询的示例
以下查询返回位于商店编号(`store_id`)为`1`中,其数量大于或等于`30`的产品的产品编号列表:
~~~sql
SELECT
product_id
FROM
production.stocks
WHERE
store_id = 1 AND quantity >= 30;
~~~
执行上面查询语句,得到以下结果 -
![](https://img.kancloud.cn/c5/62/c5622e5803070c46adc0f8fc38fbafb0_1382x711.png)
可以将上面的查询用作子查询,如以下查询所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
product_id IN (
SELECT
product_id
FROM
production.stocks
WHERE
store_id = 1 AND quantity >= 30
)
ORDER BY
product_name;
~~~
执行上面查询语句,得到以下结果 -
![](https://www.yiibai.com/uploads/article/2019/02/18/085213_10322.png)
在这个例子中:
* 首先,子查询返回了产品ID列表。
* 其次,外部查询检索产品名称和产品ID与子查询返回的任何值匹配的产品价格。
>[danger] ## 6:) [BETWEEN]- 测试值是否在指定范围值之间。
## SQL Server BETWEEN运算符简介
`BETWEEN`运算符是一个逻辑运算符,用于指定要测试值的范围。
以下是`BETWEEN`运算符的语法:
~~~sql
column | expression BETWEEN start_expression AND end_expression
~~~
在上面语法中,
* `column | expression` - 指定要测试的列或表达式。
* 将`start_expression`和`end_expression`放在`BETWEEN`和`AND`关键字之间。 `start_expression`,`end_expression`和要测试的表达式必须具有相同的数据类型。
如果要测试的表达式大于或等于`start_expression`的值且小于或等于`end_expression`的值,则`BETWEEN`运算符返回`TRUE`。
可以使用大于或等于(`>=`)且小于或等于(`<=`)来替换`BETWEEN`运算符,如下所示:
~~~sql
column | expression <= end_expression AND column | expression >= start_expression
~~~
使用`BETWEEN`运算符的条件比使用比较运算符`>=`,`<=`和逻辑运算符AND的条件更具可读性。
要取消`BETWEEN`运算符的结果,请使用`NOT BETWEEN`运算符,如下所示:
~~~sql
column | expression NOT BETWEEN start_expression AND end_expresion
~~~
如果列或表达式中的值小于`start_expression`的值且大于`end_expression`的值,则`NOT BETWEEN`将返回`TRUE`。 它相当于以下条件:
~~~sql
column | expression < start_expression AND column | expression > end_expression
~~~
请注意,如果`BETWEEN`或`NOT BETWEEN`的任何输入为`NULL`,则结果为`UNKNOWN`。
## SQL Server BETWEEN示例
让我们举一些使用`BETWEEN`运算符的例子,以了解它是如何工作的。
#### A. SQL Server BETWEEN两个数字示例
我们将使用[示例数据库]中的`products`表进行演示,表的结构如下:
![](https://www.yiibai.com/uploads/article/2019/02/17/212629_63233.png)
以下查询查找价格介于`149.99`和`199.99`之间的产品:
~~~sql
SELECT
product_id,
product_name,
list_price
FROM
production.products
WHERE
list_price BETWEEN 149.99 AND 199.99
ORDER BY
list_price;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/d1/f0/d1f09f530099aafb0faefb367657232d_640x524.png)
要获得价格不在`149.99`和`199.99`范围内的产品,请使用`NOT BETWEEN`运算符,如下所示:
~~~sql
SELECT
product_id,
product_name,
list_price
FROM
production.products
WHERE
list_price NOT BETWEEN 149.99 AND 199.99
ORDER BY
list_price;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/e0/be/e0beb679e96ab6702cebed45b547b95f_638x532.png)
#### B. SQL Server BETWEEN两个日期示例
请考虑以下`orders`表,结构如下所示:
![](https://www.yiibai.com/uploads/article/2019/02/18/143712_76918.png)
以下查询查找客户在2017年1月15日至2017年1月17日期间下的订单:
~~~sql
SELECT
order_id,
customer_id,
order_date,
order_status
FROM
sales.orders
WHERE
order_date BETWEEN '20170115' AND '20170117'
ORDER BY
order_date;
~~~
执行上面查询语句,得到以下结果:
![](https://img.kancloud.cn/17/06/1706b3dc43a38f4b0cccfbcde3c566f2_638x527.png)
请注意,要指定日期常量,请使用格式:`'YYYYMMDD'`,其中`YYYY`是`4`位数年份,例如:`2019`,`MM`是`2`位数月份,例如:`01`,`DD`是`2`位数日,例如`15`。
>[danger] ## 7:) [LIKE]- 检查字符串是否与指定的模式匹配。
## SQL Server LIKE运算符简介
SQL Server `LIKE`是一个逻辑运算符,用于确定字符串是否与指定的模式匹配。 模式可以包括常规字符和通配符。`LIKE`运算符用于:`SELECT`,`UPDATE`和`DELETE`语句的`WHERE`子句中,以根据模式匹配过滤行。
以下说明了SQL Server `LIKE`运算符的语法:
~~~sql
column | expression LIKE pattern [ESCAPE escape_character]
~~~
**pattern**
模式是要在列或表达式中搜索的字符序列。它可以包含以下有效通配符:
* 通配符百分比(`%`):任何零个或多个字符的字符串。
* 下划线(`_`)通配符:任何单个字符。
* `[list of characters]`通配符:指定集合中的任何单个字符。
* `[character-character]`:指定范围内的任何单个字符。
* `[^]`:不在列表或范围内的任何单个字符。
通配符使`LIKE`运算符比等于(`=`)和不等于(`!=`)字符串比较运算符更灵活。
**转义符**
* 转义字符指示`LIKE`运算符将通配符视为常规字符。转义字符没有默认值,必须仅计算为一个字符。
如果列或表达式与指定的模式匹配,则`LIKE`运算符返回`TRUE`。要取消`LIKE`运算符的结果,可以使用`NOT`运算符,如下所示:
~~~sql
column | expression NOT LIKE pattern [ESCAPE escape_character]
~~~
## SQL Server LIKE示例
请参阅示例数据库中的以下`customers`表:
![](https://www.yiibai.com/uploads/article/2019/02/18/145608_42028.png)
#### A. %(百分比)通配符示例
以下示例查找姓氏(`last_name`)以字母`z`开头的客户:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE 'z%'
ORDER BY
first_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/4b/c0/4bc052bd5d570059cadc817676d6cedb_1387x712.png)
以下示例返回姓氏(`last_name`)以字符串`er`结尾的客户信息:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '%er'
ORDER BY
first_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/59/d9/59d9ae3b9b8534865ff3059bad9561f0_1376x712.png)
以下语句检索姓氏(`last_name`)以字母`t`开头并以字母`s`结尾的客户:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE 't%s'
ORDER BY
first_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/f4/f2/f4f24d7d15b1e077bd19f7a55992b9e5_1388x710.png)
#### B. \_(下划线)通配符示例
下划线代表单个字符。 例如,以下语句返回第二个字符为字母`u`的客户:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '_u%'
ORDER BY
first_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/46/a7/46a793599ce46f25f1d122159cecc702_1374x715.png)
在上面查询中,`_u%`模式解释说明如下 -
* 第一个下划线字符(`_`)匹配任何单个字符。
* 第二个字母`u`完全匹配字母`u`。
* 第三个字符`%`匹配任何字符序列。
#### C. \[list of characters\]通配符示例
带有字符列表的方括号,例如:`[ABC]`表示单个字符,必须是列表中指定的字符之一。
例如,以下查询返回姓氏(`last_name`)中第一个字符为`Y`或`Z`的客户:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '[YZ]%'
ORDER BY
last_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/ed/a4/eda4d21f9d036529ffd1074d6edcf88a_1382x710.png)
#### D. \[character-character\]通配符示例
具有字符范围的方括号,例如`[A-C]`表示必须在指定范围内的单个字符。
例如,以下查询查找客户,其中姓氏中的第一个字符是范围`A`到`C`中的字母:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '[A-C]%'
ORDER BY
first_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/eb/16/eb164c427c0ac0589add1d14f151153d_1379x710.png)
#### E. \[^字符列表或范围\]通配符示例
带有插入符号(`^`)后跟范围,例如`[A-C]`或字符列表,例如`[^ABC]`的方括号表示不在指定范围或字符列表中的单个字符。
例如,以下查询返回姓氏中的第一个字符不是范围`A`到`X`中的字母的客户信息:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '[^A-X]%'
ORDER BY
last_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/55/c2/55c283bd21808c06d367ec5f4a5f42f2_1382x709.png)
#### F. NOT LIKE运算符示例
以下示例使用`NOT LIKE`运算符查找名字中第一个字符不是字母`A`的客户:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
first_name NOT LIKE 'A%'
ORDER BY
first_name;
~~~
执行上面查询语句,得到下结果 -
![](https://img.kancloud.cn/c5/4b/c54bcb03beae5625ea9b9a348f034f46_1376x709.png)
>[danger] ## 8:) [列和表别名]- 显示如何使用列别名来更改查询输出和表别名的标题,以提高查询的可读性
1.使用as 字句来改变结果集中列的名称
2.使用"空格" 来改变结果集中列的别名
- 第一章-测试理论
- 1.1软件测试的概念
- 1.2测试的分类
- 1.3软件测试的流程
- 1.4黑盒测试的方法
- 1.5AxureRP的使用
- 1.6xmind,截图工具的使用
- 1.7测试计划
- 1.8测试用例
- 1.9测试报告
- 2.0 正交表附录
- 第二章-缺陷管理工具
- 2.1缺陷的内容
- 2.2书写规范
- 2.3缺陷的优先级
- 2.4缺陷的生命周期
- 2.5缺陷管理工具简介
- 2.6缺陷管理工具部署及使用
- 2.7软件测试基础面试
- 第三章-数据库
- 3.1 SQL Server简介及安装
- 3.2 SQL Server示例数据库
- 3.3 SQL Server 加载示例
- 3.3 SQL Server 中的数据类型
- 3.4 SQL Server 数据定义语言DDL
- 3.5 SQL Server 修改数据
- 3.6 SQL Server 查询数据
- 3.7 SQL Server 连表
- 3.8 SQL Server 数据分组
- 3.9 SQL Server 子查询
- 3.10.1 SQL Server 集合操作符
- 3.10.2 SQL Server聚合函数
- 3.10.3 SQL Server 日期函数
- 3.10.4 SQL Server 字符串函数
- 第四章-linux
- 第五章-接口测试
- 5.1 postman 接口测试简介
- 5.2 postman 安装
- 5.3 postman 创建请求及发送请求
- 5.4 postman 菜单及设置
- 5.5 postman New菜单功能介绍
- 5.6 postman 常用的断言
- 5.7 请求前脚本
- 5.8 fiddler网络基础及fiddler简介
- 5.9 fiddler原理及使用
- 5.10 fiddler 实例
- 5.11 Ant 介绍
- 5.12 Ant 环境搭建
- 5.13 Jmeter 简介
- 5.14 Jmeter 环境搭建
- 5.15 jmeter 初识
- 5.16 jmeter SOAP/XML-RPC Request
- 5.17 jmeter HTTP请求
- 5.18 jmeter JDBC Request
- 5.19 jmeter元件的作用域与执行顺序
- 5.20 jmeter 定时器
- 5.21 jmeter 断言
- 5.22 jmeter 逻辑控制器
- 5.23 jmeter 常用函数
- 5.24 soapUI概述
- 5.25 SoapUI 断言
- 5.26 soapUI数据源及参数化
- 5.27 SoapUI模拟REST MockService
- 5.28 Jenkins的部署与配置
- 5.29 Jmeter+Ant+Jenkins 搭建
- 5.30 jmeter脚本录制
- 5.31 badboy常见的问题
- 第六章-性能测试
- 6.1 性能测试理论
- 6.2 性能测试及LoadRunner简介
- 第七章-UI自动化
- 第八章-Maven
- 第九章-测试框架
- 第十章-移动测试
- 10.1 移动测试点及测试流程
- 10.2 移动测试分类及特点
- 10.3 ADB命令及Monkey使用
- 10.4 MonkeyRunner使用
- 10.5 appium工作原理及使用
- 10.6 Appium环境搭建(Java版)
- 10.7 Appium常用函数(Java版)
- 10.8 Appium常用函数(Python版)
- 10.9 兼容性测试