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

这篇具有很好参考价值的文章主要介绍了读SQL学习指南(第3版)笔记06_连接和集合。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

读SQL学习指南(第3版)笔记06_连接和集合文章来源地址https://www.toymoban.com/news/detail-678696.html

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. 将相邻查询放入括号中,以覆盖复合查询默认的自顶向下的处理方式

到了这里,关于读SQL学习指南(第3版)笔记06_连接和集合的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 读SQL学习指南(第3版)笔记08_视图和索引

    3.1.3.1. Oracle Database用户另一种选择可以保护数据表的行列数据安全 3.1.3.2. VPD允许用户对数据表施加策略,服务器据此对用户的查询进行修改 5.10.4.1. sql 5.12.1.1. 平衡树索引(balanced-tree index) 5.12.1.1.1. B树索引(B-tree index) 5.12.1.2. MySQL、Oracle Database和SQL Server均默认采用B树

    2024年02月10日
    浏览(32)
  • 读SQL学习指南(第3版)笔记09_条件逻辑与事务

    1.3.1.1. Oracle的decode()函数 1.3.1.2. MySQL的if()函数 1.3.1.3. SQL Server的coalesce()函数 1.3.2.1. 在Oracle Database、SQL Server、MySQL、PostgreSQL、IBM UDB等数据库中实现 1.3.3.1. 用于select、insert、update和delete语句 1.3.4.1. sql 1.3.4.2. mysql 1.3.5.1. simple case expression 1.3.5.2. 类似于搜索型case表达式,但

    2024年02月10日
    浏览(32)
  • 读SQL学习指南(第3版)笔记12_时间函数和分析函数

    1.6.3.1. SQL Server的getutcdate() 1.6.3.2. MySQL的utc_timestamp() 1.8.2.1. 对于每个登录的用户可能有所不同 1.8.2.2. 改变当前会话的时区设置 1.8.2.3. mysql> SET time_zone = \\\'Europe/Zurich\\\'; 2.4.1.1. 年份,包括世纪 2.4.1.2. 1000--9999 2.4.2.1. 月份 2.4.2.2. 01 (1月)~12 (12月) 2.4.3.1. 日 2.4.3.2. 01~31 2.4.4.1

    2024年02月10日
    浏览(30)
  • 读SQL学习指南(第3版)笔记07_分组和子查询

    2.1.1.1. 查询返回的每个值都是由聚合函数生成的 2.1.1.2. 没有使用group by子句 2.1.1.3. 只有一个隐式分组 2.1.1.3.1. payment数据表中的所有行 2.2.1.1. 添加一个group by子句来指定聚合函数应该应用于哪个分组 2.6.2.1. 因为在评估where子句时,分组尚未生成,因而必须将分组过滤条件

    2024年02月11日
    浏览(31)
  • 读SQL学习指南(第3版)笔记03_创建和填充数据库

    3.2.3.1. ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT; 5.4.3.1. sql 5.4.3.2. %a 星期几的简写,比如Sun、Mon、... 5.4.3.3. %b 月份名称的简写,比如Jan、Feb、... 5.4.3.4. %c 月份的数字形式(0…12) 5.4.3.5. %d 月份中的天数(00…31) 5.4.3.6. %f 微秒数(000000…999999) 5.4.3.7. %H 24小

    2024年02月11日
    浏览(37)
  • 读SQL学习指南(第3版)笔记10_元数据与大数据

    1.3.19.1. system catalog 5.7.2.1. 服务器会检查数据表的元数据,以确定实际需要包含哪些分区 5.7.3.1. 只有那些包含查询所需数据的分区才会被包含在内 5.7.4.1. 财务数据可能需要在线保存7年,如果数据表已根据事务日期进行分区,就可以撤销数据保存时长超过7年的分区 5.9.1.1. 

    2024年02月10日
    浏览(32)
  • 读SQL学习指南(第3版)笔记11_字符串函数和数值函数

    2.5.3.1. SQL Server 2005还包括varchar(max)数据类型,并建议使用其代替text类型,text类型将在未来的某个版本中被删除 2.9.7.1. 如果使用的是MySQL,可以通过内建函数quote()来实现,该函数会将整个字符串放入引号内并对其中任意的引号/撇号进行转义 2.9.7.2. mysql 2.9.7.3. 在检索数据用

    2024年02月10日
    浏览(37)
  • 从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)

    1.1数组和集合的区别 相同点 都是容器,可以存储多个数据 不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类 1.2集合类体系结构 1.3Collection 集合概述和使用 Collec

    2024年02月10日
    浏览(27)
  • 从零开始学习 Java:简单易懂的入门指南之Map集合(二十三)

    1.1Map集合概述和特点 Map集合概述 Map集合的特点 双列集合,一个键对应一个值 键不可以重复,值可以重复 Map集合的基本使用 1.2Map集合的基本功能 方法介绍 方法名 说明 V put(K key,V value) 添加元素 V remove(Object key) 根据键删除键值对元素 void clear() 移除所有的键值对元素 boolean con

    2024年02月09日
    浏览(36)
  • 从零开始学习 Java:简单易懂的入门指南之不可变集合、方法引用(二十六)

    1.1 什么是不可变集合 ​ 是一个长度不可变,内容也无法修改的集合 1.2 使用场景 ​ 如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。 ​ 当集合对象被不可信的库调用时,不可变形式是安全的。 简单理解: ​ 不想让别人修改集合中的内容 比如

    2024年02月07日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包