ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
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.使用"空格" 来改变结果集中列的别名