文章目录
- 1. WHERE
- WHERE 子句概述
- WHERE 子句示例
- 1) 使用 WHERE 子句和等于运算符 (=) 示例
- 2) 使用 WHERE 子句和 AND 运算符示例
- 3) 使用 WHERE 子句和 OR 运算符示例
- 4) 使用 WHERE 子句和 IN 运算符示例
- 5) 使用 WHERE 子句和 LIKE 运算符示例
- 6) 将 WHERE 子句与 BETWEEN 运算符一起使用的示例
- 7) 使用带有不等于运算符 (<>) 的 WHERE 子句示例
- 2. LIMIT
- PostgreSQL LIMIT 子句简介
- 语法
- PostgreSQL LIMIT 示例
- 1) 使用 LIMIT 限制返回行数的示例
- 2) 使用 LIMIT 和 OFFSET 的示例
- 3) 使用 LIMIT OFFSET 获取头部/底部 N 行
- 3. FETCH
- FETCH 子句简介
- FETCH 对比 LIMIT
- PostgreSQL FETCH 示例
- 4. IN
- IN 运算符语法
- PostgreSQL IN 运算符示例
- PostgreSQL NOT IN 运算符
- 带有子查询的 IN 表达式
- 5. BETWEEN
- BETWEEN 运算符简介
- PostgreSQL BETWEEN 运算符示例
- 6. LIKE
- LIKE 运算符简介
- PostgreSQL LIKE 运算符 – 模式匹配示例
- 简单的 PostgreSQL LIKE 示例
- PostgreSQL NOT LIKE 示例
- PostgreSQL 对 LIKE 运算符的扩展
- 7. IS NULL
- NULL 和 IS NULL 运算符简介
- IS NOT NULL 运算符
1. WHERE
WHERE 子句概述
SELECT
语句返回表中一列或多列的所有行。要选择满足指定条件的行,可以使用WHERE
子句。
PostgreSQL 的WHERE
子句的语法如下:
SELECT select_list
FROM table_name
WHERE condition
ORDER BY sort_expression
WHERE
子句出现在SELECT
语句的FROM
子句之后。WHERE
子句使用condition
来过滤从SELECT
列表子句返回的行。
condition
的计算结果必须为真、假或未知。它可以是布尔表达式或使用AND
和OR
运算符的布尔表达式的组合。
该查询仅返回满足WHERE
子句中condition
的行。换句话说,只有导致condition
计算结果为 true 的行才会包含在结果集中。
PostgreSQL 计算WHERE
子句的时间点,在FROM
子句之后,在SELECT
列表和ORDER BY
子句之前:
如果在SELECT
列表子句中使用列别名,则不能在WHERE
子句中使用它们。
除了SELECT
语句之外,您还可以使用UPDATE
和DELETE
语句中的WHERE
子句来指定要更新或删除的行。
要构成WHERE
子句中的条件,请使用比较运算符和逻辑运算符:
运算符 | 描述 |
---|---|
= | 等于 |
> | 大于 |
< | 小于 |
>= | 大等于 |
<= | 小等于 |
<> 或 != | 不等于 |
AND | 逻辑运算符 AND |
OR | 逻辑运算符 OR |
IN | 如果值与列表中的任何值匹配,则返回 true |
BETWEEN | 如果值介于某个值范围之间,则返回 true |
LIKE | 如果值与模式匹配则返回 true |
IS NULL | 如果值为 NULL,则返回 true |
NOT | 对其他运算符的结果求反 |
WHERE 子句示例
1) 使用 WHERE 子句和等于运算符 (=) 示例
以下语句使用WHERE
子句查找名字为Jamie
的客户:
SELECT
last_name,
first_name
FROM
customer
WHERE
first_name = 'Jamie';
2) 使用 WHERE 子句和 AND 运算符示例
以下示例通过使用AND
逻辑运算符组合两个布尔表达式,来查找名字为Jamie
和姓氏为rice
的客户:
SELECT
last_name,
first_name
FROM
customer
WHERE
first_name = 'Jamie' AND
last_name = 'Rice';
3) 使用 WHERE 子句和 OR 运算符示例
此示例使用OR
运算符查找姓氏为Rodriguez
或名字为Adam
的客户:
SELECT
first_name,
last_name
FROM
customer
WHERE
last_name = 'Rodriguez' OR
first_name = 'Adam';
4) 使用 WHERE 子句和 IN 运算符示例
如果要将某个字符串与列表中的任何字符串进行匹配,可以使用IN
运算符。
例如,以下语句返回名字为Ann
,或Anne
,或Annie
的客户:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name IN ('Ann','Anne','Annie');
5) 使用 WHERE 子句和 LIKE 运算符示例
要查找与指定模式匹配的字符串,可以使用LIKE
运算符。以下示例返回名字以字符串Ann
开头的所有客户:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name LIKE 'Ann%'
%
称为匹配任何字符串的通配符。模式'Ann%'
匹配任何以'Ann'
开头的字符串。
6) 将 WHERE 子句与 BETWEEN 运算符一起使用的示例
以下示例使用BETWEEN
运算符查找名字以字母A
开头且包含 3 到 5 个字符的客户。
如果某个值在某个值范围内,则BETWEEN
运算符返回 true。
SELECT
first_name,
LENGTH(first_name) name_length
FROM
customer
WHERE
first_name LIKE 'A%' AND
LENGTH(first_name) BETWEEN 3 AND 5
ORDER BY
name_length;
在此示例中,我们使用LENGTH()
函数获取输入字符串的字符数。
7) 使用带有不等于运算符 (<>) 的 WHERE 子句示例
此示例查找名字以Bra
开头且姓氏不是Motley
的客户:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name LIKE 'Bra%' AND
last_name <> 'Motley';
请注意,您可以互换使用!=
运算符和<>
运算符,因为它们是等效的。
2. LIMIT
PostgreSQL LIMIT 子句简介
PostgreSQL 的 LIMIT
子句是 SELECT
语句的一个可选部分,它可以帮助您限制查询结果中的行数。
语法
LIMIT
子句的基本语法如下:
SELECT select_list
FROM table_name
ORDER BY sort_expression
LIMIT row_count;
这条语句会返回查询结果中的 row_count
行。如果 row_count
设置为零,查询将返回空集;如果设置为 NULL
,查询将返回所有行。
如果您想在返回 row_count
行之前跳过一些行,请在 LIMIT
子句之后放置 OFFSET
子句,如下所示:
SELECT select_list
FROM table_name
LIMIT row_count OFFSET row_to_skip;
这条语句首先跳过 row_to_skip
行,然后返回查询生成的 row_count
行。如果 row_to_skip
为零,则该语句将像没有 OFFSET
子句一样工作。
由于表可能以未指定的顺序存储行,因此当您使用 LIMIT
子句时,应始终使用 ORDER BY
子句来控制行顺序。如果不使用 ORDER BY
子句,则可能会得到具有未指定行顺序的结果集。
PostgreSQL LIMIT 示例
1) 使用 LIMIT 限制返回行数的示例
此示例使用 LIMIT
子句来获取按 film_id
排序的前五部电影:
SELECT
film_id,
title,
release_year
FROM
film
ORDER BY
film_id
LIMIT 5;
2) 使用 LIMIT 和 OFFSET 的示例
要检索按 film_id
排序的从第四部开始的 4 部电影,请同时使用 LIMIT
和 OFFSET
子句,如下所示:
SELECT
film_id,
title,
release_year
FROM
film
ORDER BY
film_id
LIMIT 4 OFFSET 3;
3) 使用 LIMIT OFFSET 获取头部/底部 N 行
通常,经常使用 LIMIT
子句从表中选择具有最高或最低值的行。
例如,要获取租赁费用最高的 10 部电影,您可以按租赁费率降序对电影进行排序,并使用 LIMIT
子句获取前 10 部电影。以下查询说明了这个想法:
SELECT
film_id,
title,
rental_rate
FROM
film
ORDER BY
rental_rate DESC
LIMIT 10;
3. FETCH
FETCH 子句简介
为了限制查询返回的行数,您经常使用LIMIT
子句。LIMIT
子句被许多关系数据库管理系统广泛使用,例如 MySQL、H2 和 HSQLDB。但是,LIMIT
子句不是 SQL 标准。
为了符合 SQL 标准,PostgreSQL 支持FETCH
子句来检索查询返回的行数。
请注意,
FETCH
子句是在 SQL:2008 中作为 SQL 标准的一部分引入的。
下面说明了 PostgreSQL 的FETCH
子句的语法:
OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ row_count ] { ROW | ROWS } ONLY
在这个语法中:
ROW
是ROWS
的同义词,FIRST
是NEXT
的同义词。所以你可以互换使用它们。start
是一个整数,必须为零或正数。默认情况下,如果未指定OFFSET
子句,则该值为零。如果start
大于结果集中的行数,则不返回任何行;row_count
是 1 或更大。默认情况下,如果不显式指定row_count
,则默认值为 1。
由于表中存储的行顺序是未指定的,因此在使用FETCH
子句时应始终带有ORDER BY
子句,以使返回的结果集中的行顺序一致。
请注意,在 SQL:2008 标准中,
OFFSET
子句必须位于FETCH
子句之前。但是,OFFSET
和FETCH
子句可以以任何顺序出现在 PostgreSQL 中。
FETCH 对比 LIMIT
FETCH
子句在功能上等同于LIMIT
子句。如果您计划使您的应用程序与其他数据库系统兼容,则应该使用FETCH
子句,因为它遵循 SQL 标准。
PostgreSQL FETCH 示例
以下语句使用 FETCH 子句查询按标题升序排列的第一部电影:
SELECT
film_id,
title
FROM
film
ORDER BY
title
FETCH FIRST ROW ONLY;
输出:
film_id | title
---------+------------------
1 | Academy Dinosaur
(1 row)
它相当于以下查询:
SELECT
film_id,
title
FROM
film
ORDER BY
title
FETCH FIRST 1 ROW ONLY;
以下语句使用FETCH
子句查询按标题排序的前五部电影:
SELECT
film_id,
title
FROM
film
ORDER BY
title
FETCH FIRST 5 ROW ONLY;
输出:
film_id | title
---------+------------------
1 | Academy Dinosaur
2 | Ace Goldfinger
3 | Adaptation Holes
4 | Affair Prejudice
5 | African Egg
(5 rows)
以下语句返回按标题排序的前五部电影之后的接下来的五部电影:
SELECT
film_id,
title
FROM
film
ORDER BY
title
OFFSET 5 ROWS
FETCH FIRST 5 ROW ONLY;
输出:
film_id | title
---------+------------------
6 | Agent Truman
7 | Airplane Sierra
8 | Airport Pollock
9 | Alabama Devil
10 | Aladdin Calendar
(5 rows)
4. IN
IN 运算符语法
您可以在WHERE
子句中使用IN
运算符来检查某个值是否与值列表中的任何值匹配。
IN
运算符的语法如下:
value IN (value1,value2,...)
如果value
匹配列表中的任何值,即value1
, value2
, … ,则IN
运算符返回 true。
值列表可以是文字值(如数字、字符串)列表,或者SELECT
语句的结果,如下:
value IN (SELECT column_name FROM table_name);
括号内的查询称为子查询,它是嵌套在另一个查询中的查询。请注意,您将在后续教程中了解有关子查询的更多信息。
PostgreSQL IN 运算符示例
假设你想知道 ID 为 1 和 2 的客户的租赁信息,你可以在WHERE
子句中使用IN
运算符,如下所示:
SELECT customer_id,
rental_id,
return_date
FROM
rental
WHERE
customer_id IN (1, 2)
ORDER BY
return_date DESC;
以下查询使用等于 (=
) 和OR
运算符替代 IN 运算符。它等价于上面的查询:
SELECT
rental_id,
customer_id,
return_date
FROM
rental
WHERE
customer_id = 1 OR customer_id = 2
ORDER BY
return_date DESC;
使用IN
运算符的查询比使用等于 (=
) 和OR
运算符的查询更短且更具可读性。此外,PostgreSQL 使用IN
运算符执行查询比使用OR
运算符列表执行相同查询要快得多。
PostgreSQL NOT IN 运算符
您可以将IN
运算符与NOT
运算符结合使用来选择其值与列表中的值不匹配的行。
例如,以下语句查找 ID 不为 1 或 2 的客户的所有租赁。
SELECT
customer_id,
rental_id,
return_date
FROM
rental
WHERE
customer_id NOT IN (1, 2);
与IN
运算符类似,您可以使用不等于 (<>
) 和AND
运算符来编写NOT IN
运算符:
SELECT
customer_id,
rental_id,
return_date
FROM
rental
WHERE
customer_id <> 1
AND customer_id <> 2;
此查询返回与上面使用NOT IN
运算符的查询相同的输出。
带有子查询的 IN 表达式
以下语句从rental
表中查询返回日期为2005-05-27
的客户 ID 列表:
SELECT customer_id
FROM rental
WHERE CAST (return_date AS DATE) = '2005-05-27'
ORDER BY customer_id;
由于此查询返回一个值列表,因此您可以将其用作IN
运算符的输入,如下所示:
SELECT
customer_id,
first_name,
last_name
FROM
customer
WHERE
customer_id IN (
SELECT customer_id
FROM rental
WHERE CAST (return_date AS DATE) = '2005-05-27'
)
ORDER BY customer_id;
5. BETWEEN
BETWEEN 运算符简介
您可以使用BETWEEN
运算符将一个值与一系列值进行匹配。下面说明了BETWEEN
运算符的语法:
value BETWEEN low AND high;
如果value
大等于low
值且小等于high
值,则表达式返回 true,否则返回 false。
您可以使用大等于 (>=
) 或小等于 (<=
) 运算符重写BETWEEN
运算符,如下所示:
value >= low and value <= high
如果要检查值是否超出范围,可以将NOT
运算符与BETWEEN
运算符组合起来,如下所示:
value NOT BETWEEN low AND high;
以下表达式等效于使用NOT
和BETWEEN
运算符的表达式:
value < low OR value > high
PostgreSQL BETWEEN 运算符示例
以下查询使用BETWEEN
运算符选择金额在 8 到 9(美元)之间的付款:
SELECT
customer_id,
payment_id,
amount
FROM
payment
WHERE
amount BETWEEN 8 AND 9;
要获取金额不在 8 和 9 范围内的付款,请使用以下查询:
SELECT
customer_id,
payment_id,
amount
FROM
payment
WHERE
amount NOT BETWEEN 8 AND 9;
如果要检查日期范围内的值,则应使用 ISO 8601 格式的文字日期,即 YYYY-MM-DD。例如,要获取付款日期在2007-02-07
和2007-02-15
之间的付款,请使用以下查询:
SELECT
customer_id,
payment_id,
amount,
payment_date
FROM
payment
WHERE
payment_date BETWEEN '2007-02-07' AND '2007-02-15';
6. LIKE
LIKE 运算符简介
假设您想要找到一位客户,但您不记得她的确切名字。但是,您可以记得她的名字以类似Jen
开头。
如何从数据库中找到准确的客户?您可以通过查看名字列来查找customer
表中的客户,看看是否有任何以Jen
开头的值。但是,如果客户表包含大量行,则此过程可能会非常耗时。
幸运的是,您可以使用 PostgreSQL 的LIKE
运算符,通过以下查询将客户的名字与字符串进行匹配:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name LIKE 'Jen%';
请注意,其中WHERE
子句包含一个特殊表达式:first_name
、LIKE
运算符和包含百分号 (%
) 的字符串。字符串'Jen%'
称为模式。
该查询返回first_name
列值以Jen
开头且后跟任意字符序列的行。这种技术称为模式匹配。
您可以通过将文字值与通配符组合来构造模式,并使用LIKE
或NOT LIKE
运算符来查找匹配项。PostgreSQL 为您提供了两个通配符:
- 百分号 (
%
) 匹配任何零个或多个字符的序列。 - 下划线符号 (
_
) 匹配任何单个字符。
PostgreSQL LIKE
运算符的语法如下:
如果value
与pattern
匹配,则表达式返回 true。
要否定LIKE
运算符,请按如下方式使用NOT
运算符:
当value
与pattern
不匹配时,NOT LIKE
运算符返回 true。
如果模式不包含任何通配符,则LIKE
运算符的行为类似于等于 (=
) 运算符。
PostgreSQL LIKE 运算符 – 模式匹配示例
让我们看一些使用LIKE
运算符的例子。
简单的 PostgreSQL LIKE 示例
请查看以下示例:
SELECT
'foo' LIKE 'foo', -- true
'foo' LIKE 'f%', -- true
'foo' LIKE '_o_', -- true
'bar' LIKE 'b_'; -- false
怎么运行的。
- 第一个表达式返回 true,因为
foo
模式不包含任何通配符,因此该LIKE
运算符的作用类似于等于 (=
) 运算符。 - 第二个表达式返回 true,因为它匹配以字母
f
开头且后跟任意数量的字符的任何字符串。 - 第三个表达式返回 true,因为模式 (
_o_
) 匹配以任何单个字符开头、后跟字母o
并以任何单个字符结尾的任何字符串。 - 第四个表达式返回 false,因为模式
b_
与以字母开头b
且后跟任何单个字符的任何字符串匹配。
可以在模式的开头和/或结尾使用通配符。
例如,以下查询返回名字包含er
字符串的客户,比如Jenifer
、Kimberly
等。
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name LIKE '%er%'
ORDER BY
first_name;
您可以将百分号 (%
) 与下划线 (_
) 组合起来构建模式,如下例所示:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name LIKE '_her%'
ORDER BY
first_name;
模式_her%
匹配任何符合以下条件的字符串:
- 以任意单个字符 (
_
) 开头。 - 后面跟着文字字符串
her
。 - 并且以任意数量的字符结尾。
返回的名字是 Cheryl、Sherri、Sherry 和 Therasa。
PostgreSQL NOT LIKE 示例
以下查询使用NOT LIKE
运算符查找名字不以Jen
开头的客户:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name NOT LIKE 'Jen%'
ORDER BY
first_name
PostgreSQL 对 LIKE 运算符的扩展
PostgreSQL 支持类似于LIKE
运算符的ILIKE
运算符。此外,ILIKE
运算符匹配值时不区分大小写。例如:
SELECT
first_name,
last_name
FROM
customer
WHERE
first_name ILIKE 'BAR%';
模式BAR%
匹配以BAR
、Bar
、BaR
等开头的任何字符串。如果您改用LIKE
运算符,查询将不会返回任何行。
PostgreSQL 还提供了一些类似于LIKE
, NOT LIKE
, ILIKE
和NOT ILIKE
的运算符,如下所示:
运算符 | 等价于 |
---|---|
~~ | LIKE |
~~* | ILIKE |
!~~ | NOT LIKE |
!~~* | NOT ILIKE |
7. IS NULL
NULL 和 IS NULL 运算符简介
在数据库世界中,NULL 意味着缺少信息或不适用。NULL 不是一个值,因此,您不能将它与任何其他值(例如数字或字符串)进行比较。NULL 与值的比较将始终得到 NULL,这意味着结果未知。
此外,NULL 不等于 NULL,因此以下表达式返回 NULL:
假设您有一个contacts
表存储联系人的名字、姓氏、电子邮件和电话号码。在记录联系人时,您可能不知道联系人的电话号码。
为了解决这个问题,您可以将phone
列定义为可为空列,并在保存联系人信息时将 NULL 插入到phone
列中。
CREATE TABLE contacts(
id INT GENERATED BY DEFAULT AS IDENTITY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(255) NOT NULL,
phone VARCHAR(15),
PRIMARY KEY (id)
);
如果执行CREATE TABLE
语句时出现错误,您的 PostgreSQL 版本可能不支持标识列
语法。在这种情况下,您可以使用以下语句:
CREATE TABLE contacts(
id SERIAL,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(255) NOT NULL,
phone VARCHAR(15),
PRIMARY KEY (id)
);
以下语句插入两个联系人,一个有电话号码,另一个没有:
INSERT INTO contacts(first_name, last_name, email, phone)
VALUES ('John','Doe','john.doe@rockdata.net',NULL),
('Lily','Bush','lily.bush@rockdata.net','(408-234-2764)');
要查找没有电话号码的联系人,您可以使用以下语句:
SELECT
id,
first_name,
last_name,
email,
phone
FROM
contacts
WHERE
phone = NULL;
该语句不返回任何行。这是因为WHERE
子句中的表达式phone = NULL
始终返回 false。
即使电话列中存在 NULL,表达式NULL = NULL
也会返回 false。这是因为 NULL 不等于任何值,甚至它本身也不等于。
要检查值是否为 NULL,请使用IS NULL
运算符:
如果值为 NULL,则表达式返回 true,否则返回 false。
因此,要获取电话列中没有存储任何电话号码的联系人,请使用以下语句:
SELECT
id,
first_name,
last_name,
email,
phone
FROM
contacts
WHERE
phone IS NULL;
IS NOT NULL 运算符
要检查值是否不为 NULL,请使用IS NOT NULL
运算符:
如果值不为 NULL,则表达式返回 true;如果值为 NULL,则表达式返回 false。
例如,要查找有电话号码的联系人,您可以使用以下语句:
SELECT
id,
first_name,
last_name,
email,
phone
FROM
contacts
WHERE
phone IS NOT NULL;