读SQL学习指南(第3版)笔记06_连接和集合

news2025/1/20 16:22:56

1. 连接

1.1. 笛卡儿积

1.1.1. 交叉连接(cross join)

1.1.2. 查询并没有指定两个数据表应该如何连接,数据库服务器就生成了笛卡儿积

1.1.2.1. 两个数据表的所有排列组合

1.1.3. 很少会用到(至少不会特意用到)

1.1.3.1. 使用频率并不高

1.1.4. mysql

-> SELECT c.first_name, c.last_name, a.address
    -> FROM customer c JOIN address a;

1.1.5. 为2020年的每一天生成一行,但是数据库中没有包含每天一行的数据表

1.1.5.1. 涉及交叉连接、外连接、日期函数、分组、集合运算(union all)和聚合函数(count())

1.1.5.2. sql

 SELECT '2020-01-01' dt
UNION ALL
SELECT '2020-01-02' dt
UNION ALL
SELECT '2020-01-03' dt
UNION ALL
...
...
...
SELECT '2020-12-29' dt
UNION ALL
SELECT '2020-12-30' dt
UNION ALL
SELECT '2020-12-31' dt

1.1.5.3. mysql

 -> SELECT ones.num + tens.num + hundreds.num
    -> FROM
    -> (SELECT 0 num UNION ALL
    -> SELECT 1 num UNION ALL
    -> SELECT 2 num UNION ALL
    -> SELECT 3 num UNION ALL
    -> SELECT 4 num UNION ALL
    -> SELECT 5 num UNION ALL
    -> SELECT 6 num UNION ALL
    -> SELECT 7 num UNION ALL
    -> SELECT 8 num UNION ALL
    -> SELECT 9 num) ones
    -> CROSS JOIN
    -> (SELECT 0 num UNION ALL
    -> SELECT 10 num UNION ALL
    -> SELECT 20 num UNION ALL
    -> SELECT 30 num UNION ALL
    -> SELECT 40 num UNION ALL
    -> SELECT 50 num UNION ALL
    -> SELECT 60 num UNION ALL
    -> SELECT 70 num UNION ALL
    -> SELECT 80 num UNION ALL
    -> SELECT 90 num) tens
    -> CROSS JOIN
    -> (SELECT 0 num UNION ALL
    -> SELECT 100 num UNION ALL
    -> SELECT 200 num UNION ALL
    -> SELECT 300 num) hundreds;

1.1.5.4. 如果生成{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}、{0, 10, 20, 30, 40, 50, 60, 70, 80, 90}和{0,100, 200, 300}这3个集合的笛卡儿积,并将这3列的值相加,就可以得到包含0~399的所有数值的400行结果集

1.1.5.5. mysql

 -> SELECT DATE_ADD('2020-01-01',
    ->   INTERVAL (ones.num + tens.num + hundreds.num) DAY) dt
    -> FROM
    ->  (SELECT 0 num UNION ALL
    ->   SELECT 1 num UNION ALL
    ->   SELECT 2 num UNION ALL
    ->   SELECT 3 num UNION ALL
    ->   SELECT 4 num UNION ALL
    ->   SELECT 5 num UNION ALL
    ->   SELECT 6 num UNION ALL
    ->   SELECT 7 num UNION ALL
    ->   SELECT 8 num UNION ALL
    ->   SELECT 9 num) ones
    ->   CROSS JOIN
    ->  (SELECT 0 num UNION ALL
    ->   SELECT 10 num UNION ALL
    ->   SELECT 20 num UNION ALL
    ->   SELECT 30 num UNION ALL
    ->   SELECT 40 num UNION ALL
    ->   SELECT 50 num UNION ALL
    ->   SELECT 60 num UNION ALL
    ->   SELECT 70 num UNION ALL
    ->   SELECT 80 num UNION ALL
    ->   SELECT 90 num) tens
    ->   CROSS JOIN
    ->  (SELECT 0 num UNION ALL
    ->   SELECT 100 num UNION ALL
    ->   SELECT 200 num UNION ALL
    ->   SELECT 300 num) hundreds
    -> WHERE DATE_ADD('2020-01-01',
    ->   INTERVAL (ones.num + tens.num + hundreds.num) DAY) < '2021-01-01'
    -> ORDER BY 1;

1.1.5.6. 无须人为介入,结果集会自动包含额外的闰日(2月29日),这是由数据库服务器通过将2020年1月1日加上59天计算得出

1.2. 内连接

1.2.1. 增加了连接类型(注意关键字inner)

1.2.2. mysql

 -> SELECT c.first_name, c.last_name, a.address
    -> FROM customer c JOIN address a
    ->   ON c.address_id = a.address_id;

1.2.3. sql

SELECT c.first_name, c.last_name, a.address
FROM customer c INNER JOIN address a
  ON c.address_id = a.address_id;

1.2.4. 如果用于连接两个数据表的列名相同,则可以使用using子句替代on

1.2.4.1. sql

SELECT c.first_name, c.last_name, a.address
FROM customer c INNER JOIN address a
  USING (address_id);

1.2.4.2. using是一种只能在某些特定情况下使用的简写表示法

1.3. 外连接(outer join)

1.3.1. 如果要将一个数据表中的所有行全部纳入结果集,不管其在另一个数据表中是否存在匹配

1.3.2. mysql

 -> SELECT f.film_id, f.title, count(i.inventory_id) num_copies
    -> FROM film f
    ->   LEFT OUTER JOIN inventory i
    ->   ON f.film_id = i.film_id
    -> GROUP BY f.film_id, f.title;

1.3.3. 关键字left和right只是告知服务器哪个数据表的数据可以不足

1.3.4. outer关键字是可选的,可以使用A left join B来代替

1.4. 自然连接(natural join)

1.4.1. 依靠多个数据表之间相同的列名来推断适合的连接条件

1.4.2. mysql

 -> SELECT c.first_name, c.last_name, date(r.rental_date)
    -> FROM customer c
    ->   NATURAL JOIN rental r;
Empty set (0.04 sec)

1.4.3. 数据库服务器检查数据表定义并添加了连接条件r.customer_id = c.customer_id

1.4.4. 应该避免使用这种连接类型,而使用带有显式连接条件的内连接

1.5. 连接的旧方法

1.5.1. mysql

 -> SELECT c.first_name, c.last_name, a.address
    -> FROM customer c, address a
    -> WHERE c.address_id = a.address_id;

1.5.2. 不需要on子句

1.5.3. from子句中的数据表名以逗号分隔

1.5.4. 连接条件出现在where子句中

1.6. ANSI连接语法

1.6.1. 连接条件和过滤条件被分隔在两个不同的子句中(on子句和where子句),使得查询语句更易于理解

1.6.2. 两个数据表的连接条件出现在其各自单独的on子句中,这样就不太可能错误地忽略连接条件

1.6.3. 使用SQL92连接语法的查询语句可以在各种数据库服务器间移植,而旧语法在不同服务器上的表现略有不同

1.7. 连接顺序

1.7.1. 各数据表在from子句中出现的顺序并不重要

1.7.1.1. 服务器使用从数据库对象收集的统计信息,在3个数据表中选择一个作为起点(所选择的数据表被称为驱动表),然后确定其他数据表的连接顺

1.7.2. 如果认为查询语句中的数据表应该始终以特定的顺序连接,可以将数据表按照需要的顺序排列

1.7.2.1. 在MySQL中指定straight_join关键字

1.7.2.1.1. sql
SELECT STRAIGHT_JOIN c.first_name, c.last_name, ct.city
FROM city ct
  INNER JOIN address a
  ON a.city_id = ct.city_id
  INNER JOIN customer c
  ON c.address_id = a.address_id

1.7.2.2. 在SQL Server中请求force order选项

1.7.2.3. 在Oracle Database中使用ordered或leading优化器

1.7.3. 三路外连接

1.7.3.1. mysql

-> SELECT f.film_id, f.title, i.inventory_id, r.rental_date
    -> FROM film f
    ->   LEFT OUTER JOIN inventory i
    ->   ON f.film_id = i.film_id
    ->   LEFT OUTER JOIN rental r
    ->   ON i.inventory_id = r.inventory_id
    -> WHERE f.film_id BETWEEN 13 AND 15;

1.8. 自连接

1.8.1. mysql

-> SELECT f.title, f_prnt.title prequel
    -> FROM film f
    ->   INNER JOIN film f_prnt
    ->   ON f_prnt.film_id = f.prequel_film_id
    -> WHERE f.prequel_film_id IS NOT NULL;

2. 集合

2.1. 在对两个数据集执行集合运算时

2.1.1. 两个数据集的列数必须相等

2.1.2. 两个数据集各列的数据类型必须相同

2.1.2.1. 数据库服务器必须能够将一种数据类型转换成另一种数据类型

2.2. union运算符

2.2.1. mysql

 -> SELECT 1 num, 'abc' str
    -> UNION
    -> SELECT 9 num, 'xyz' str;

2.2.2. union会对组合后的集合进行排序并去除重复项

2.2.3. union all则不然

2.3. intersect运算符

2.3.1. ANSI SQL规范中定义了用于执行交集运算的intersect运算符

2.3.2. ANSI SQL规范还提供了不去除重复行的intersect all运算符

2.3.2.1. 唯一实现了intersect all运算符的数据库服务器是IBM DB2 Universal Server

2.3.3. MySQL 8.0版还未实现intersect运算符

2.3.4. Oracle或SQL Server 2008中可以使用

2.4. except运算符

2.4.1. ANSI SQL规范提供了执行差集运算的except运算符

2.4.2. ANSI SQL规范还提供了except all运算符

2.4.2.1. 只有IBM的 DB2 Universal Server实现了该运算符

2.4.3. MySQL 8.0版也没有实现except运算符

2.4.4. Oracle Database需要使用非ANSI兼容的minus运算符替代except运算符

2.5. 对符合查询结果排序

2.5.1. mysql

 -> SELECT a.first_name fname, a.last_name lname
    -> FROM actor a
    -> WHERE a.first_name LIKE 'J%' AND a.last_name LIKE 'D%'
    -> UNION ALL
    -> SELECT c.first_name, c.last_name
    -> FROM customer c
    -> WHERE c.first_name LIKE 'J%' AND c.last_name LIKE 'D%'
    -> ORDER BY lname, fname;

2.6. 集合运算的优先级

2.6.1. 包含3个或以上查询语句的复合查询,是以自顶向下的顺序来评估查询的

2.6.2. 根据ANSI SQL规范,intersect运算符拥有比其他集合运算符更高的优先级

2.6.3. 可以将查询放入括号内,以明确指定查询的执行顺序

2.6.3.1. MySQL目前还不允许在复合查询中使用括号

2.6.3.2. 将相邻查询放入括号中,以覆盖复合查询默认的自顶向下的处理方式

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/943405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NameNode 故障无法重新启动解决方法

文章目录 NameNode 进程挂掉NameNode 进程挂掉且数据丢失 NameNode 进程挂掉 如果只是单纯的进程挂掉了,可以直接使用下列命令进行重启: hdfs --daemon start namenode示例: NameNode 进程挂掉且数据丢失 这种情况就不可以直接通过重启解决…

com.mysql.jdbc.PacketTooBigException: Packet for query is too large(windows)

使用mysql查询数据的时候报错: Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1078 > 1024). You can change this value on the server by setting the max_allowed_packet variable. 这是因为mysql的server默认接受数据…

java项目mysql转postgresql

特殊函数 : mysql: find_in_set(?, ancestors) postgresql: ? ANY (string_to_array(ancestors,,)) mysql: date_format(t1.oper_time, %Y-%m-%d) postgresql: rksj::date to_char(inDate,YYYY-MM-DD) mysql&am…

基于北斗RTK+UWB矿山智能人车定位系统

露天矿山开采环境复杂,作业危险系数高,安全生产隐患多。智能人车定位技术在保障露天矿山安全生产方面具有重要作用。通过实时监测人员和车辆的位置和行动,可以有效防止事故发生、提高工作效率和管理水平。 华安联大以露天矿山安全生产为出发…

Ubuntu 下安装Qt5.12.12无法输入中文解决方法

Ubuntu 下安装Qt5.12.12无法输入中文解决方法 一,环境: (1)VMware Workstation 15 Pro (2)Ubuntu 20.04 (3)Qt 5.12.12 64bits (4)Qt Creator 5.0.2 &#…

基于 OV5640 摄像头理论知识讲解-成像和采样原理

基于OV2640/ OV5640 的图像采集显示系统系列文章目录: (1)基于 OV5640 摄像头理论知识讲解-成像和采样原理 (2)基于 OV5640 摄像头理论知识讲解-数字接口和控制接口 (3)基于 OV5640 摄像头理论知…

Qt应用开发(基础篇)——字体选择器 QFontDialog

一、前言 QFontDialog类继承于QDialog,是一个设计用来选择字体的对话框部件。 对话框窗口QDialog QFontDialog字体选择对话框,设计用来让用户选择某一种字体,一般用于文本编辑窗口、标签显示和一些需要文本输入的场景。你可以直接使用静态函数…

2、DVWA——命令注入

文章目录 一、命令注入1.1 概述1.2 判断命令注入流程 二、low2.1 通关思路2.2.源码分析 三、Medium3.1 通关思路3.2 源码分析 四、high4.1 通关思路4.2 源码分析 五、impossible六、总结 一、命令注入 1.1 概述 命令注入的目标是通过易受攻击的应用程序在主机操作系统上执行任…

『赠书活动 | 第十八期』《深入浅出SSD:固态存储核心技术、原理与实战》

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 『赠书活动 | 第十八期』 本期书籍:《深入浅出SSD:固态存储核心技术、原理与实战》 赠书规则:评论区:点赞&…

【力扣每日一题】2023.8.29 带因子的二叉树

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一些元素,让我们用这些元素连接形成特定的二叉树,每种元素可以使用任意次数,形成的二叉树要…

【深度解析】朗逸与宝来汽车:哪款更适合你?

在汽车市场中,朗逸和宝来都是非常受欢迎的车型。它们各自都有独特的优点和缺点,那么,究竟哪款车更适合你呢?让我们一起来深度解析一下。 朗逸,作为大众的入门级车型,以其稳定的性能和较高的性价比赢得了消费…

深入详解ThreadLocal

本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 文章目录 什么是ThreadLocalThreadLocal 原理set方法get方法remove方法 ThreadLocal 的Hash算法ThreadLocal …

海川润泽气泡水位计 重磅上线

一、概述 以市场为导向,海川润泽推出新款气泡水位计(型号:HC-QPSW10-S)。气泡水位计具有测量精度高,免气瓶,免测井,免维护,抗振动,寿命长等特点,特别适用于流…

印刷行业MES系统解决方案

印刷行业存在许多问题,这些问题可能因地区、技术和市场变化而有所不同。以下是一些可能的印刷行业现存问题: 1.环保问题:印刷过程中使用的化学品和材料可能对环境造成污染。废墨、废纸、有毒化学品等的处理和处理成为一个重要的问题。 2.…

优思学院|六西格玛推行为什么会失败?应如何避免?

六西格玛项目可以为企业带来丰厚的经验和巨大的利益;然而,并非所有的项目都能达到预期的效果。根据一项在国外的调查发现,在184家受访公司中,80.6%的公司声称六西格玛工作未能成功实现他们的预期的价值,74.1%的公司说他…

UG\NX二次开发 代工分享的“单个体XY排料工具”源码

文章作者:代宇(Q:873058673) 简介: 单个体XY排料,昨天代工在开发群里分享了一个排料的视频,我觉得挺有意思,就私聊要来了源码,经过作者同意可以分享给大家。请欣赏: 效果: 代码: //单个体XY排料 代工QQ:873058673 //-------------------------------…

亥姆霍兹线圈的几个特点

亥姆霍兹线圈可以用于磁学、电子学和核物理学等领域的实验研究中,是一种常见的基础实验仪器。亥姆霍兹线圈有以下几个特点: 1、磁场均匀性好:由于该线圈的结构和定位方式,使得两个线圈的磁场强度和方向都非常均匀,可以…

R语言和Python用泊松过程扩展:霍克斯过程Hawkes Processes分析比特币交易数据订单到达自激过程时间序列...

全文下载链接:http://tecdat.cn/?p25880 本文描述了一个模型,该模型解释了交易的聚集到达,并展示了如何将其应用于比特币交易数据。这是很有趣的,原因很多。例如,对于交易来说,能够预测在短期内是否有更多…

IDA Python 使用总结

环境配置 切换 python 版本 运行 IDA 安装目录下的 idapyswitch.exe ,选择使用的 python 解释器。 在 PyCharm 中写 IDAPython 脚本 在 PyCharm 的设置→项目→Python解释器点击设置选择全部显示… 点击如下位置添加自定义路径 路径选择 IDA Pro 7.6\python\3…

国标GB28181视频平台EasyGBS国标平台激活码授权提示“授权失败”的问题解决方案

EasyGBS平台是基于国标GB28181协议的视频云服务平台,支持多路设备接入,并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等多种格式的视频流。平台可为大数据等综合性监管平台提供极强的视频能力,既能作为能力平台为业务层提供接口调用…