SQL必知必会
陈旸
清华大学计算机博士
立即订阅
10179 人已学习
课程目录
已完结 49 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词丨SQL可能是你掌握的最有用的技能
免费
第一章:SQL语法基础篇 (19讲)
01丨了解SQL:一门半衰期很长的语言
02丨DBMS的前世今生
03丨学会用数据库的方式思考SQL是如何执行的
04丨使用DDL创建数据库&数据表时需要注意什么?
05丨检索数据:你还在SELECT * 么?
06丨数据过滤:SQL数据过滤都有哪些方法?
07丨什么是SQL函数?为什么使用SQL函数可能会带来问题?
08丨什么是SQL的聚集函数,如何利用它们汇总表的数据?
09丨子查询:子查询的种类都有哪些,如何提高子查询的性能?
10丨常用的SQL标准有哪些,在SQL92中是如何使用连接的?
11丨SQL99是如何使用连接的,与SQL92的区别是什么?
12丨视图在SQL中的作用是什么,它是怎样工作的?
13丨什么是存储过程,在实际项目中用得多么?
14丨什么是事务处理,如何使用COMMIT和ROLLBACK进行操作?
15丨初识事务隔离:隔离的级别有哪些,它们都解决了哪些异常问题?
16丨游标:当我们需要逐条处理数据时,该怎么做?
17丨如何使用Python操作MySQL?
18丨SQLAlchemy:如何使用Python ORM框架来操作MySQL?
19丨基础篇总结:如何理解查询优化、通配符以及存储过程?
第二章:SQL性能优化篇 (18讲)
20丨当我们思考数据库调优的时候,都有哪些维度可以选择?
21丨范式设计:数据表的范式有哪些,3NF指的是什么?
22丨反范式设计:3NF有什么不足,为什么有时候需要反范式设计?
23丨索引的概览:用还是不用索引,这是一个问题
24丨索引的原理:我们为什么用B+树来做索引?
25丨Hash索引的底层原理是什么?
26丨索引的使用原则:如何通过索引让SQL查询效率最大化?
27丨从数据页的角度理解B+树查询
28丨从磁盘I/O的角度理解SQL查询的成本
29丨为什么没有理想的索引?
30丨锁:悲观锁和乐观锁是什么?
31丨为什么大部分RDBMS都会支持MVCC?
32丨查询优化器是如何工作的?
33丨如何使用性能分析工具定位SQL执行慢的原因?
34丨答疑篇:关于索引以及缓冲池的一些解惑
35丨数据库主从同步的作用是什么,如何解决数据不一致问题?
36丨数据库没有备份,没有使用Binlog的情况下,如何恢复数据?
37丨SQL注入:你的SQL是如何被注入的?
第三章:认识DBMS (7讲)
38丨如何在Excel中使用SQL语言?
39丨WebSQL:如何在H5中存储一个本地数据库?
40丨SQLite:为什么微信用SQLite存储聊天记录?
41丨初识Redis:Redis为什么会这么快?
42丨如何使用Redis来实现多用户抢票问题
43丨如何使用Redis搭建玩家排行榜?
44丨DBMS篇总结和答疑:用SQLite做词云
第四章:SQL项目实战 (3讲)
45丨数据清洗:如何使用SQL对数据进行清洗?
46丨数据集成:如何对各种数据库进行集成和转换?
47丨如何利用SQL对零售数据进行分析?
结束语 (1讲)
结束语 | 互联网的下半场是数据驱动的时代
SQL必知必会
登录|注册

11丨SQL99是如何使用连接的,与SQL92的区别是什么?

陈旸 2019-07-05
上节课我们讲解了 SQL92 标准,在它之后又提出了 SQL99 标准。现在各大 DBMS 中对 SQL99 标准的支持度更好。你一定听说过 LEFT JOIN、RIGHT JOIN 这样的操作符,这实际上就是 SQL99 的标准,在 SQL92 中它们是用(+)代替的。SQL92 和 SQL99 标准原理类似,只是 SQL99 标准的可读性更强。
今天我就来讲解一下 SQL99 标准中的连接查询,在今天的课程中你需要重点掌握以下几方面的内容:
SQL99 标准下的连接查询是如何操作的?
SQL99 与 SQL92 的区别是什么?
在不同的 DBMS 中,使用连接需要注意什么?

SQL99 标准中的连接查询

上一篇文章中,我用 NBA 球员的数据表进行了举例,包括了三张数据表 player、team 和 height_grades。
其中 player 表为球员表,一共有 37 个球员,如下所示:
team 表为球队表,一共有 3 支球队,如下所示:
height_grades 表为身高等级表,如下所示:
接下来我们看下在 SQL99 标准中,是如何进行连接查询的?

交叉连接

交叉连接实际上就是 SQL92 中的笛卡尔乘积,只是这里我们采用的是 CROSS JOIN。
我们可以通过下面这行代码得到 player 和 team 这两张表的笛卡尔积的结果:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《SQL必知必会》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(64)

  • 一步
    所有的连接类型,是不是都先对连接的表做笛卡尔,然后在根据条件进行数据筛选的?

    对于上一个问题,可能没有表达清楚,我想问的是,各种连接的内部执行步骤,比如先根据连接生成中间表数据,然后在连接类型,on,where进行数据筛选得到数据的步骤

    作者回复: 完整的SELECT语句内部执行顺序是:
    1、FROM子句组装数据(包括通过ON进行连接)
    2、WHERE子句进行条件筛选
    3、GROUP BY分组
    4、使用聚集函数进行计算;
    5、HAVING筛选分组;
    6、计算所有的表达式;
    7、SELECT 的字段;
    8、ORDER BY排序
    9、LIMIT筛选

    2019-07-05
    1
    18
  • mickey
    # 编写 SQL 查询语句,查询不同身高级别(对应 height_grades 表)对应的球员数量(对应 player 表)
    SELECT h.height_level AS '身高级别', COUNT(player_id) AS '球员数量'
    FROM height_grades as h LEFT JOIN player as p ON height BETWEEN h.height_lowest AND h.height_highest
    GROUP BY height_level;

    身高级别 球员数量
    ---------------------------
    A 18
    B 14
    C 5
    D 0
    2019-07-18
    12
  • 墨禾
    跟踪到第四个星期的专栏学习,这里对前面的知识点做个阶段性的总结。首先我自己是个用过mssql、mysql做过项目开发的人,所以我学习这几节课的专栏比较轻松,除了对过去的项目做个复盘提醒之外,还有些新的收获——从纵向广度、横向深度了解sql语言的特点。
    -----------------------------------------------------------------------------------------------------
    1、纵向广度
    几乎每节专栏都会对 mysql 和 oracle 的知识点做对比,让我从不同之中寻找练习,迁移默化之中加强知识迁移的能力,让我在技术不断迭代更新的时代减少一些焦虑感。
    -------------------------------------------------------------------------------------------------------
    2、横向深度
    -- 熟悉了更多的专业术语(如DML、DDL、DQL、TCL、SQL92、SQL99):之前在实操的时候,只管用,而不管知识属于哪个体系,这样的方法有些粗暴而低效,因为有时候出错的时候,在不理解知识整体结构和专业术语的情况下,难以定位具体的出错点,也就难以检索到对应的解决办法。

    -- 理清楚mysql的知识脉络结构,学习一种思维模式:每一节专栏都有对应的思维导图,看完文字听完语音,掌握了知识要点后,可能忽略了知识之间的联系,思维导图可以很清晰地展现知识之间的联系。其实看老师的专栏的结构组织,也就是一种学习【思维模式】,让我逐渐地转变学生思维,一年后,以更为优秀的姿态走向社会。

    -- 摆正心态:大步迈进,小步迭代。看到知识点都是自己学过的,有时候会觉得有些亏。 但反过来想,老师这么厉害的人,尚且与我们一起学习基础知识,我有什么理由好高骛远? 所以我要做到每节课不落地认真做笔记,最重要的还是要多实践,实践方能出真知。

    作者回复: 多谢支持,不同企业使用的DBMS会有不同,所以在竞争激烈的环境下掌握不同的RDBMS的使用有时候会是一种优势。
    我们知道数据库都有自己的“方言”,同时也都遵循一定的规范标准,所以对规范标准的掌握有时候更重要,“方言”在实际使用中查阅相应的RDBMS文档,当然日常积累也很重要
    专栏里不同人所处的阶段不同,所以需要先交付基础,当然即使是基础篇也需要了解底层原理,这样对后续的SQL优化很有必要。
    赞下总结笔记的习惯,我接触很多同学,一般来说经常写总结笔记的同学收获更大,在实际工作中也会游刃有余。

    2019-07-05
    2
    11
  • lmingzhi
    "需要注意的是 MySQL 不支持全外连接,否则的话全外连接会返回左表和右表中的所有行。当表之间有匹配的行,会显示内连接的结果。当某行在另一个表中没有匹配时,那么会把另一个表中选择的列显示为空值。"

    请问一下,这里的否则,指的是支持全外连接的数据库吗?

    作者回复: 对的 就是讲解下如果支持全外连接的数据库是怎样的结果。Oracle支持全外连接 FULL JOIN,而MySQL不支持,不过想要写全外连接的话,可以用 左外连接 UNION 右外连接,比如:
    SELECT * FROM player LEFT JOIN team ON player.team_id = team.team_id
    UNION
    SELECT * FROM player RIGHT JOIN team ON player.team_id = team.team_id

    2019-07-05
    6
  • 一步
    对于连接执行的顺序,有点不太确定,希望老师讲解下各种连接及相关的关键字 执行的顺序?
    2019-07-05
    5
  • 一叶知秋
    SELECT g.height_level, count(*)
    FROM height_grades as g, player as p
    WHERE p.height
    BETWEEN g.height_lowest AND g.height_highest
    GROUP BY g.height_level;
    执行结果:
    +--------------+----------+
    | height_level | count(*) |
    +--------------+----------+
    | A | 18 |
    | B | 14 |
    | C | 5 |
    +--------------+----------+
    3 rows in set (0.01 sec)

    一下午真正追完了~~~~
    2019-07-05
    1
    2
  • 夜路破晓
    建议多表连接使用SQL99标准.好了本章结束,继续!
    2019-07-05
    2
  • 圆子蛋
    SELECT h.height_level,COUNT(*) AS num FROM height_grades AS h JOIN player AS p ON p.player_height BETWEEN h.height_lowest AND h.height_highest GROUP BY h.height_level ORDER BY h.height_level ASC
    2019-07-05
    2
  • 白了少年头
    select height_level, count(player_name) as player_num from player as p left join height_grades as h on p.height between h.height_lowest and h.height_highest group by height_level;
    +--------------+------------+
    | height_level | player_num |
    +--------------+------------+
    | A | 18 |
    | B | 14 |
    | C | 5 |
    +--------------+------------+
    3 rows in set (0.00 sec)
    2019-07-05
    1
  • 郡鸿
    select h.height_level,count(*) as num from player p join height_grades h on p.height between h.height_lowest and h.height_highest group by h.height_level;
    2019-07-05
    1
  • pain
    把链接条件写在 join 里面跟写在 where 会有什么不同吗。老师能不能讲一下,工作的时候常常遇到,发现有时候筛选条件放的位置没有影响,有时候又是有两者差别又很大
    2019-07-05
    1
  • Geek_635558
    结果相同可以有N种写法,其实很多时候更应该关注查询的效率如何。希望可以详解

    作者回复: 对的,我们需要先了解都有哪些写法,然后在正确性的基础上提升SQL优化的能力,这部分会在后面陆续讲到。
    SQL优化有很多维度,最常用的考虑可以从两方面入手:如何建立有效的索引策略(包括主键),以及不要在WHERE的字段中做函数运算。
    在此基础上,我们还会了解事务处理,锁的机制,不同RDBMS的特点和使用等等。

    2019-07-05
    1
  • Krison
    我SQL很差,之前订了课程一直没时间学。今天捡起来。这个sql想了很久,总算是想出来了。加油!
    SELECT
    CONCAT( '身高级别', ' - ', b.height_level ),
    CONCAT( '球员数量', ' - ', count( b.height_level ) )
    FROM
    `player` AS a
    LEFT JOIN height_grades AS b ON a.height BETWEEN b.height_lowest
    AND b.height_highest
    GROUP BY
    b.height_level;
    ------结果如下------------
    身高级别 - A 球员数量 - 18
    身高级别 - B 球员数量 - 14
    身高级别 - C 球员数量 - 5
    2019-11-27
  • 爬行的蜗牛
    SELECT COUNT(*), h.height_level
       FROM player as p JOIN height_grades as h
       ON p.height BETWEEN h.height_lowest AND h.height_highest
       GROUP BY h.height_level;
    2019-11-25
  • Victor.
    SELECT DISTINCT h.height_level,count(*) AS num FROM player AS p LEFT JOIN height_grades AS h ON height BETWEEN h.height_lowest AND h.height_highest GROUP BY h.height_level
    2019-11-11
  • whaleFall_
    # 查询不同身高级别对应的球员数量
    SELECT
        h.height_level,
        COUNT(*) AS '球员数量'
    FROM player AS p
    JOIN height_grades AS h
    ON height BETWEEN h.height_lowest AND h.height_highest
    GROUP BY h.height_level
    2019-10-23
  • Coool
    练习:
    SELECT
        h.height_level, COUNT(*) AS player_num
    FROM
        player AS p
            LEFT JOIN
        height_grades AS h ON p.height BETWEEN h.height_lowest AND h.height_highest
    GROUP BY h.height_level;
    2019-10-21
  • 爱思考的仙人球
    我记得还有一个inner join 内连接,和问中的ON 连接很像
    2019-10-16
  • chenysh38
    mysql> select count(*), height_level
        -> from player as p, height_grades as h
        -> where p.height between h.height_lowest and h.height_highest
        -> group by height_level
        -> order by height_level;
    +----------+--------------+
    | count(*) | height_level |
    +----------+--------------+
    | 18 | A |
    | 14 | B |
    | 5 | C |
    +----------+--------------+
    3 rows in set (0.13 sec)
    2019-09-16
  • 森鱼
    SELECT h.height AS '身高级别', COUNT(p.player_id) AS ‘球员数量’ FROM height_grades AS h LEFT JOIN player AS p ON p.height BETWEEN h.height_lowest AND h.height_highest GROUP BY h.height_level
    2019-09-08
收起评论
64
返回
顶部