PostgreSQL-06-入门篇-集合运算

文章目录

    • [1. UNION 组合多个查询的结果集](#1. UNION 组合多个查询的结果集)
    • [2. INTERSECT 取交集](#2. INTERSECT 取交集)
      • 简介
      • [带 ORDER BY 子句的 INTERSECT 操作](#带 ORDER BY 子句的 INTERSECT 操作)
      • [PostgreSQL INTERSECT 运算符示例](#PostgreSQL INTERSECT 运算符示例)
    • [3. EXCEPT 取差集](#3. EXCEPT 取差集)
      • 简介
      • [PostgreSQL EXCEPT 运算符示例](#PostgreSQL EXCEPT 运算符示例)
      • 概括

1. UNION 组合多个查询的结果集

简介

UNION运算符将两个或多个SELECT语句的结果集组合成一个结果集。

下面说明了组合两个查询的结果集的UNION运算符的语法:

sql 复制代码
SELECT select_list_1
FROM table_expresssion_1
UNION
SELECT select_list_2
FROM table_expression_2

要使用UNION运算符组合两个查询的结果集,查询必须符合以下规则:

  • 两个查询的选择列表中列的数量和顺序必须相同。
  • 数据类型必须兼容。

UNION运算符从组合数据集中删除所有重复行。要保留重复的行,请改用UNION ALL

下面的维恩图说明了UNION工作原理:

带有 ORDER BY 子句的 UNION

UNION运算符可以将第一个查询的结果集中的行放置在第二个查询的结果集中的行之前、之后或之间。

要对最终结果集中的行进行排序,请在第二个查询中使用ORDER BY子句。

在实践中,您可能会使用UNION运算符来组合来自数据仓库或商业智能系统中未完全规范化的相似表的数据。

设置样例表

以下语句创建两个表:top_rated_filmsmost_popular_films,并向这些表中插入数据:

sql 复制代码
DROP TABLE IF EXISTS top_rated_films;
CREATE TABLE top_rated_films(
title VARCHAR NOT NULL,
release_year SMALLINT
);

DROP TABLE IF EXISTS most_popular_films;
CREATE TABLE most_popular_films(
title VARCHAR NOT NULL,
release_year SMALLINT
);

INSERT INTO 
   top_rated_films(title,release_year)
VALUES
   ('The Shawshank Redemption',1994),
   ('The Godfather',1972),
   ('12 Angry Men',1957);

INSERT INTO 
   most_popular_films(title,release_year)
VALUES
   ('An American Pickle',2020),
   ('The Godfather',1972),
   ('Greyhound',2020);

top_rated_films表中数据如下所示:

sql 复制代码
SELECT * FROM top_rated_films;

以下语句返回most_popular_films表中的数据:

sql 复制代码
SELECT * FROM most_popular_films;

PostgreSQL UNION 示例

让我们看一些使用 PostgreSQL 的UNION运算符的示例。

1) 简单的 PostgreSQL UNION 示例

以下语句使用UNION运算符组合两个表中的数据:

sql 复制代码
SELECT * FROM top_rated_films
UNION
SELECT * FROM most_popular_films;

查询返回以下结果:

由于UNION运算符删除了 1 个重复行,因此结果集中包含 5 行。

2) PostgreSQL UNION ALL 示例

以下语句使用UNION ALL运算符组合top_rated_filmsmost_popular_films表中的结果集:

sql 复制代码
SELECT * FROM top_rated_films
UNION ALL
SELECT * FROM most_popular_films;

在此示例中,重复行保留在结果集中。

3) 带 ORDER BY 子句 UNION ALL 示例

要对UNION运算符返回的结果进行排序,请将ORDER BY子句放在最后一个查询的末尾,如下所示:

sql 复制代码
SELECT * FROM top_rated_films
UNION ALL
SELECT * FROM most_popular_films
ORDER BY title;

如果将ORDER BY子句放置在每个查询的末尾,则组合结果集将不会按您预期的方式排序。

因为当UNION运算符合并每个查询的排序结果集时,它不能保证最终结果集中行的顺序。

2. INTERSECT 取交集

简介

UNIONEXCEPT运算符类似,PostgreSQL 的INTERSECT运算符将两个或多个SELECT语句的结果集组合成一个结果集。

INTERSECT运算符返回两个结果集中可用的任何行。

下图显示了INTERSECT运算符产生的最终结果集。

最终结果集由圆 A 与圆 B 相交的黄色区域表示。

下面说明了INTERSECT运算符的语法:

sql 复制代码
SELECT select_list
FROM A
INTERSECT
SELECT select_list
FROM B;

要使用INTERSECT运算符,SELECT语句中出现的列必须遵循以下规则:

  1. SELECT列表中的列数及其顺序必须相同。
  2. 列的数据类型必须兼容。

带 ORDER BY 子句的 INTERSECT 操作

如果要对INTERSECT运算符返回的结果集进行排序,请将ORDER BY放在查询列表中的最终查询处,如下所示:

sql 复制代码
SELECT select_list
FROM A
INTERSECT
SELECT select_list
FROM B
ORDER BY sort_expression;

PostgreSQL INTERSECT 运算符示例

我们将使用第一章 UNION 组合多个查询的结果集 中创建的top_rated_filmsmost_popular_films

要获取热门的同时也是评分最高的电影,您可以使用INTERSECT运算符,如下:

sql 复制代码
SELECT *
FROM most_popular_films 
INTERSECT
SELECT *
FROM top_rated_films;

结果集返回了同时出现在两个表中的一部影片。

3. EXCEPT 取差集

简介

UNIONINTERSECT运算符类似,EXCEPT运算符通过比较两个或多个查询的结果集来返回行。

EXCEPT运算符返回第一个(左)查询中不在第二个(右)查询的输出中的不同行。

下面说明了EXCEPT运算符的语法。

sql 复制代码
SELECT select_list
FROM A
EXCEPT
SELECT select_list
FROM B;

EXCEPT涉及到的查询需要遵循以下规则:

  • 两个查询中的列数及其顺序必须相同。
  • 各列的数据类型必须兼容。

下面的维恩图说明了EXCEPT运算符:

PostgreSQL EXCEPT 运算符示例

我们将使用第一章 UNION 组合多个查询的结果集 中创建的top_rated_filmsmost_popular_films

以下语句使用EXCEPT运算符查找评分最高但不受欢迎的电影:

sql 复制代码
SELECT * FROM top_rated_films
EXCEPT 
SELECT * FROM most_popular_films;

以下语句使用查询中的ORDER BY子句对EXCEPT运算符返回的结果集进行排序:

SELECT * FROM top_rated_films
EXCEPT
SELECT * FROM most_popular_films
ORDER BY title;

请注意,我们将 ORDER BY 子句放在语句末尾,以按标题对电影进行排序。

概括

  • 使用 PostgreSQL 的EXCEPT运算符获取第一个查询中未出现在第二个查询的结果集中的行。
相关推荐
夜泉_ly2 小时前
MySQL -安装与初识
数据库·mysql
qq_529835353 小时前
对计算机中缓存的理解和使用Redis作为缓存
数据库·redis·缓存
月光水岸New5 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6755 小时前
数据库基础1
数据库
我爱松子鱼5 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo6 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser7 小时前
【SQL】多表查询案例
数据库·sql
Galeoto7 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)7 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231117 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql