购物网站要多少钱,成都外贸seo,网站需要写哪些内容,建设银行优缺点引言
在结构化查询语言 (SQL)语句中#xff0c;WHERE子句限制了给定操作会影响哪些行。它们通过定义特定的条件(称为搜索条件)来实现这一点#xff0c;每一行都必须满足这些条件才能受到操作的影响。
本指南将介绍WHERE子句中使用的通用语法。它还将概述如何在单个WHERE子句…引言
在结构化查询语言 (SQL)语句中WHERE子句限制了给定操作会影响哪些行。它们通过定义特定的条件(称为搜索条件)来实现这一点每一行都必须满足这些条件才能受到操作的影响。
本指南将介绍WHERE子句中使用的通用语法。它还将概述如何在单个WHERE子句中组合多个搜索条件谓词以更细粒度的方式过滤数据以及如何使用NOT操作符排除而不是包含满足给定搜索条件的行。
虽然本指南在示例中只使用SELECT语句但这里解释的概念可以用于许多SQL操作。事实上WHERE子句是UPDATE和DELETE操作的关键组成部分。
前期准备
为了学习本指南你需要一台运行某种使用SQL的关系数据库管理系统(RDBMS)的计算机。
注意请注意许多RDBMS使用它们自己独特的SQL实现。虽然本教程中概述的命令适用于大多数RDBMS但如果你在MySQL以外的系统上测试它们确切的语法或输出可能会有所不同。
你还需要一个装载了一些示例数据的数据库和表可以在其中练习使用相关命令。
连接到MySQL并设置一个示例数据库
如果SQL数据库系统运行在远程服务器上请从本地设备SSH到服务器:
ssh sammyyour_server_ip然后打开MySQL服务器提示符将sammy替换为你的MySQL用户账户的名称:
mysql -u sammy -p创建一个名为where_db的数据库:
CREATE DATABASE where_db;如果数据库成功创建,您将收到这样的输出:
OutputQuery OK, 1 row affected (0.01 sec)要选择where_db数据库运行以下USE语句:
USE where_db;OutputDatabase changed选择where_db后在其中创建一个表。
为了理解本指南中使用的示例假设您在当地的高尔夫球场经营高尔夫联赛。你决定跟踪联盟球员参加郊游时的个人表现信息。为此您决定将信息存储在SQL数据库中。
你决定这个表需要6列:
name:每个高尔夫球手的名字使用varchar数据类型表示不超过20个字符rounds_played:每个高尔夫球手打完的总回合数用int数据类型表示best:每位高尔夫球手在单次比赛中的最佳或最低得分也用int表示。worst:每位高尔夫球手在单次比赛中的最差或最高得分同样用int表示average:每个高尔夫球手在他们打过的几轮中得分的近似平均值。这一列将保存decimal类型的值限制为最多4位其中一位在小数点的右侧wins:每个高尔夫球手在比赛小组中得分最低的轮数用int类型表示
运行下面的CREATE TABLE语句来创建一个名为golfers的表它包含以下6列:
CREATE TABLE golfers (
name varchar(20),
rounds_played int,
best int,
worst int,
average decimal (4,1),
wins int
);然后加载包含一些示例数据的golfers表。运行下面的INSERT INTO操作来添加代表7名联赛高尔夫球手的7行数据:
INSERT INTO golfers
VALUES
(George, 22, 68, 103, 84.6, 3),
(Pat, 25, 65, 74, 68.7, 9),
(Grady, 11, 78, 118, 97.6, 0),
(Diane, 23, 70, 92, 78.8, 1),
(Calvin, NULL, 63, 76, 68.5, 7),
(Rose, NULL, 69, 84, 76.7, 4),
(Raymond, 18, 67, 92, 81.3, 1);请注意其中两行rounds_played的值是NULL。出于本教程的目的假设这些高尔夫球手没有报告他们打了多少轮因此这些值被记录为NULL。
你可能还注意到每个高尔夫球手的best值小于他们的worst值。这是因为在常见的高尔夫规则中高尔夫球手的得分是由他们将球打入球场每个洞所需的击球次数决定的总击球次数最少的人就是获胜者。因此与大多数其他运动不同高尔夫球手的最佳分数会比最差分数低。
有了这些你就可以开始学习如何在SQL中使用WHERE子句了。
使用WHERE子句过滤数据
在SQL中语句是任何发送到数据库系统的操作它将执行某种任务如创建表插入或删除数据或更改列或表的结构。SQL语句是由各种子句,由特定的关键字和他们需要的信息。
正如引言中提到的WHERE子句允许你过滤掉受SQL操作影响的某些行数据。在查询中,WHERE之后跟上查询条件如以下示例:
SELECT columns_to_query
FROM table_to_query
WHERE search_condition;WHERE关键字后面是一个搜索条件。一个搜索条件是由一个或多个谓词或表达式组成的集合这些谓词或表达式可以计算一个或多个值表达式并返回“true”、“false”或“unknown”的结果。注意在搜索条件只包含一个谓词的情况下术语“搜索条件”和“谓词”是同义词。
WHERE子句搜索条件中的谓词可以有多种形式但它们通常遵循以下语法:
. . .
WHERE column_name OPERATOR value_expression
. . .在SQL中值表达式——有时也称为标量表达式——是任何返回单个值的表达式。值表达式可以是字面量比如字符串或数值也可以是数学表达式。不过大多数情况下在WHERE子句的搜索条件中至少有一个值表达式是列名。
当运行包含WHERE子句的SQL查询时数据库管理系统将对FROM子句定义的逻辑表中的每一行应用搜索条件。然后它将只返回所有谓词在搜索条件中求值为“true”的行。
为了说明这个想法运行下面的查询。这将返回golfers表的name列中的所有值:
SELECT name
FROM golfers
WHERE (2 2) 4;这个查询包含一个WHERE子句但它没有指定列名而是使用(2 2)作为第一个值表达式并测试它是否等于第二个值表达式4。因为(2 2) 总是等于4所以对于每一行这个搜索条件都计算为true。因此结果集中的每一行都会被返回:
Output---------
| name |
---------
| George |
| Pat |
| Grady |
| Diane |
| Calvin |
| Rose |
| Raymond |
---------
7 rows in set (0.01 sec)这个WHERE子句不是很有用因为它总是求值为“true”并总是返回表中的每一行。如前所述在WHERE子句搜索条件中通常至少使用一个列名作为值表达式。当运行查询时数据库系统将依次对每一行应用搜索条件。通过在搜索条件中提供列名作为值表达式你告诉DBMS使用该列中每行的值作为迭代搜索条件时的值表达式。
以下查询的WHERE子句对每一行应用了比前一个示例更排他的搜索条件。它将返回任何wins列值等于1的行中的name和wins值:
SELECT name, wins
FROM golfers
WHERE wins 1;只有两名高尔夫球手刚好赢了一轮因此这个查询只返回这两行:
Output---------------
| name | wins |
---------------
| Diane | 1 |
| Raymond | 1 |
---------------
2 rows in set (0.01 sec)前面的例子使用等号()测试是否两个值表达式是等价的,但您使用的运营商取决于您想要使用什么类型的谓词过滤结果集。
SQL标准定义了18种类型的谓词尽管并不是所有的SQL实现都包含这些谓词。下面是5种最常用的谓词类型以及对每种类型及其使用的操作符的简要说明。
比较
比较谓词使用比较运算符比较一个值(在查询,通常值在一个指定的列)。这6个比较运算符是:
测试两个值是否相等
SELECT name
FROM golfers
WHERE name George;Output--------
| name |
--------
| George |
--------
1 row in set (0.00 sec)测试两个值是否不相等
SELECT name, wins
FROM golfers
WHERE wins 1;Output--------------
| name | wins |
--------------
| George | 3 |
| Pat | 9 |
| Grady | 0 |
| Calvin | 7 |
| Rose | 4 |
--------------
5 rows in set (0.00 sec)测试第一个值是否小于第二个值
SELECT name, wins
FROM golfers
WHERE wins 1;Output-------------
| name | wins |
-------------
| Grady | 0 |
-------------
1 row in set (0.00 sec)测试第一个值是否大于第二个值
SELECT name, wins
FROM golfers
WHERE wins 1;Output--------------
| name | wins |
--------------
| George | 3 |
| Pat | 9 |
| Calvin | 7 |
| Rose | 4 |
--------------
4 rows in set (0.00 sec)测试第一个值是否小于或等于第二个
SELECT name, wins
FROM golfers
WHERE wins 1;Output---------------
| name | wins |
---------------
| Grady | 0 |
| Diane | 1 |
| Raymond | 1 |
---------------
3 rows in set (0.00 sec)测试第一个值是否大于或等于第二个值
SELECT name, wins
FROM golfers
WHERE wins 1;Output---------------
| name | wins |
---------------
| George | 3 |
| Pat | 9 |
| Diane | 1 |
| Calvin | 7 |
| Rose | 4 |
| Raymond | 1 |
---------------
6 rows in set (0.00 sec)NullIS NULL
使用IS NULL操作符的谓词测试给定列中的值是否为NULL。如果是则谓词的计算结果为“true”结果集中就包含了这一行:
SELECT name, rounds_played
FROM golfers
WHERE rounds_played IS NULL;Output-----------------------
| name | rounds_played |
-----------------------
| Calvin | NULL |
| Rose | NULL |
-----------------------
2 rows in set (0.00 sec)区间BETWEEN
范围谓词使用BETWEEN操作符来测试指定的列值是否落在两个值表达式之间:
SELECT name, best
FROM golfers
WHERE best BETWEEN 67 AND 73;Output---------------
| name | best |
---------------
| George | 68 |
| Diane | 70 |
| Rose | 69 |
| Raymond | 67 |
---------------
4 rows in set (0.00 sec)包含IN
成员谓词使用IN操作符来测试一个值是否是给定集合的成员:
SELECT name, best
FROM golfers
WHERE best IN (65, 67, 69, 71);Output---------------
| name | best |
---------------
| Pat | 65 |
| Rose | 69 |
| Raymond | 67 |
---------------
3 rows in set (0.00 sec)通配符%和_
模式匹配谓词使用LIKE操作符来测试一个值是否匹配包含一个或多个通配符的字符串模式也称为通配符。SQL定义了两个通配符%和_:
_: 下划线表示单个未知字符
SELECT name, rounds_played
FROM golfers
WHERE rounds_played LIKE 2_;Output-----------------------
| name | rounds_played |
-----------------------
| George | 22 |
| Pat | 25 |
| Diane | 23 |
-----------------------
3 rows in set (0.00 sec)%: 百分比符号表示零个或多个未知字符
SELECT name, rounds_played
FROM golfers
WHERE name LIKE G%;Output-----------------------
| name | rounds_played |
-----------------------
| George | 22 |
| Grady | 11 |
-----------------------
2 rows in set (0.00 sec)用AND和OR组合多个查询条件
有时候你需要比使用单个搜索条件谓词的WHERE子句提供的更细粒度的过滤结果。另一方面也可能有满足多个搜索条件之一的行在结果集中是可接受的。在这种情况下你可以编写包含多个谓词的WHERE子句分别使用AND或OR操作符。
要开始使用这些操作符请运行以下查询它从golfers表的name、best、worst和average列中返回值。它的WHERE子句包含两个查询条件由AND分隔:
SELECT name, best, worst, average
FROM golfers
WHERE best 70 AND worst 96;第一个谓词测试每一行的best值是否小于70,而第二个测试每一行的worst价值是否小于96。如果任何一个测试的结果为“false”则该行不会返回到结果集中:
Output-------------------------------
| name | best | worst | average |
-------------------------------
| Pat | 65 | 74 | 68.7 |
| Calvin | 63 | 76 | 68.5 |
| Rose | 69 | 84 | 76.7 |
| Raymond | 67 | 92 | 81.3 |
-------------------------------
4 rows in set (0.00 sec)接下来运行以下查询。这与前面的例子相同只是它用OR操作符而不是AND来分隔两个谓词:
SELECT name, best, worst, average
FROM golfers
WHERE best 70 OR worst 96;因为只有一个谓词的求值为“true”才能返回一行所以这个结果集比前面的例子多了两行:
Output-------------------------------
| name | best | worst | average |
-------------------------------
| George | 68 | 103 | 84.6 |
| Pat | 65 | 74 | 68.7 |
| Diane | 70 | 92 | 78.8 |
| Calvin | 63 | 76 | 68.5 |
| Rose | 69 | 84 | 76.7 |
| Raymond | 67 | 92 | 81.3 |
-------------------------------
6 rows in set (0.00 sec)你可以在一个WHERE子句中包含任意数量的谓词只要你用正确的语法将它们组合起来。然而随着搜索条件变得越来越复杂预测它们将过滤哪些数据变得越来越困难。
需要注意的是数据库系统通常优先考虑AND操作符。这意味着任何由AND操作符分隔的谓词(或在两个以上谓词的情况下的操作符)都被视为一个单独的、隔离的搜索条件在WHERE子句中的任何其他谓词之前进行测试。
为了说明问题运行下面的查询它从name、average、worst和rounds_played列中返回满足WHERE子句中定义的搜索条件的任何行:
SELECT name, average, worst, rounds_played
FROM golfers
WHERE average 85 OR worst 95 AND rounds_played BETWEEN 19 AND 23;这个查询首先测试由AND操作符分隔的谓词是否worst 95和rounds_played BETWEEN 19 AND 23——在当前迭代中这两个值都为“true”。如果是那么该行将出现在结果集中。但是如果任何一个求值为“false”查询将检查当前行的average值是否小于85。如果是则返回该行:
Output----------------------------------------
| name | average | worst | rounds_played |
----------------------------------------
| George | 84.6 | 103 | 22 |
| Pat | 68.7 | 74 | 25 |
| Diane | 78.8 | 92 | 23 |
| Calvin | 68.5 | 76 | NULL |
| Rose | 76.7 | 84 | NULL |
| Raymond | 81.3 | 92 | 18 |
----------------------------------------
6 rows in set (0.00 sec)您可以通过将两个或多个查询条件包装在括号中来确定它们的优先级。下面的示例与前一个相同但它封装了average 85和worst 95查询条件用OR操作符分隔放在括号中:
SELECT name, average, worst, rounds_played
FROM golfers
WHERE (average 85 OR worst 95) AND rounds_played BETWEEN 19 AND 23;因为前两个谓词被圆括号包围后续的AND操作符将它们视为一个离散的搜索条件必须求值为“true”。如果这两个谓词- average 85和worst 95——求值为“false”那么整个搜索条件求值为“false”查询会立即从结果集中删除这一行然后再继续求值下一行。
然而如果前两个谓词中的任何一个求值为“true”查询就会测试给定高尔夫球手的rounds_played值是否在19到23之间。如果是则在结果集中返回这一行:
Output---------------------------------------
| name | average | worst | rounds_played |
---------------------------------------
| George | 84.6 | 103 | 22 |
| Diane | 78.8 | 92 | 23 |
---------------------------------------
2 rows in set (0.00 sec)结果表明,通过优先级的谓词集和包装在括号,否则相同的查询可以返回结果集明显不同。
尽管并不总是需要这样做但建议在单个搜索条件中组合两个以上谓词时始终使用括号。这样做有助于使查询更可读、更容易理解。
用NOT排除结果
到目前为止本指南的所有示例都集中在如何使用WHERE子句编写查询在结果集中只包含满足指定搜索条件的行。然而你可以通过在WHERE子句中包含NOT操作符来编写排除特定行的查询。
范围、会员和模式匹配谓词的条款,包括NOT操作符通常遵循这一语法:
. . .
WHERE column_name NOT OPERATOR value_expression
. . .为了说明这一点运行下面的查询。这将返回golfers表的name列的值但其WHERE子句中的NOT操作符将导致DBMS排除所有匹配通配符模式的行:
SELECT name
FROM golfers
WHERE name NOT LIKE R%;Output--------
| name |
--------
| George |
| Pat |
| Grady |
| Diane |
| Calvin |
--------
5 rows in set (0.00 sec)当将NOT操作符添加到IS NULL谓词时情况略有不同。在这种情况下你可以将NOT放在IS和NULL之间如下面的例子所示。这个查询返回所有rounds_played值不为Null的高尔夫球手的name和rounds_played值:
SELECT name, rounds_played
FROM golfers
WHERE rounds_played IS NOT NULL;Output------------------------
| name | rounds_played |
------------------------
| George | 22 |
| Pat | 25 |
| Grady | 11 |
| Diane | 23 |
| Raymond | 18 |
------------------------
5 rows in set (0.00 sec)你也可以将NOT操作符紧跟在WHERE关键字之后。如果你根据是否满足多个搜索条件来排除行这很有用如下面的示例查询返回golfers的name、average、best和wins值:
SELECT name, average, best, wins
FROM golfers
WHERE NOT (average 80 AND best 70) OR wins 9;Output------------------------------
| name | average | best | wins |
------------------------------
| George | 84.6 | 68 | 3 |
| Pat | 68.7 | 65 | 9 |
| Grady | 97.6 | 78 | 0 |
| Diane | 78.8 | 70 | 1 |
| Raymond | 81.3 | 67 | 1 |
------------------------------
5 rows in set (0.00 sec)请注意结果集的第二行。帕特的“平均”分数不到80分她的“最佳”分数也不到70分。然而她的行仍然包含在结果集中因为NOT操作符只是对括号内的搜索条件求反。
回想一下当您将由AND或OR分隔的多个谓词包装在括号中时SQL将优先考虑这些谓词并将它们视为单个隔离的搜索条件。因此NOT操作符只排除基于前两个谓词的行: average 80和best 70。但是它包含基于第三个谓词的行wins 9。
你可以重写这个查询根据第三个条件和前两个条件将它们都包含在括号中如下所示:
SELECT name, average, best, wins
FROM golfers
WHERE NOT ((average 80 AND best 70) OR wins 9);Output------------------------------
| name | average | best | wins |
------------------------------
| George | 84.6 | 68 | 3 |
| Grady | 97.6 | 78 | 0 |
| Diane | 78.8 | 70 | 1 |
| Raymond | 81.3 | 67 | 1 |
------------------------------
4 rows in set (0.00 sec)根据SQL实现的不同如果你在比较操作符之前包含NOT数据库系统可能会认为查询语法无效。举个例子试着运行这个查询:
SELECT name
FROM golfers
WHERE name NOT Grady;对于MySQL及其衍生版本这将导致错误:
OutputERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near Grady at line 1这个错误的原因是NOT操作符通常不与比较操作符( 和)一起使用因为你可以通过将一个比较操作符替换为另一个比较操作符来实现相反的效果该比较操作符将返回第一个比较操作符将排除的行。例如你可以将等价运算符()替换为不等价运算符()。
总结
通过阅读本指南你学习了如何编写WHERE子句使查询只返回满足指定条件的行。你还学习了如何在单个查询中组合多个谓词和搜索条件以及如何使用NOT关键字从结果集中排除信息。
虽然这里显示的命令在大多数关系型数据库上都可以工作但请注意每个SQL数据库都使用自己独特的语言实现。关于每个命令及其所有选项的更完整描述读者可以查阅相应DBMS的官方文档。