MySQL数据分析进阶(五)编写复杂查询

※食用指南:文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记,笔记整理比较粗糙,主要目的自存为主,记录完整的学习过程。(图片超级多,慎看!)

【中字】SQL进阶教程 | 史上最易懂SQL教程!10小时零基础成长SQL大师!!https://www.bilibili.com/video/BV1UE41147KC/?spm_id_from=333.1007.0.0&vd_source=b287f1f4a1fa54cc438e31a0f87ef4e2

 

 

第五章:编写复杂查询

 

 

1、WRITING COMPLEX QUERIES——编写复杂查询

 

(第一步:重置数据,回到初始化,便于学习)

(之前的坑还是要补了。。。。。。)

 

执行后刷新即可

ded55da60f8f41259e58656e79554eda.png

 

 

2、SUBQUERIES——子查询

返回单一值,再在WHERE子句中和比较运算符使用

83d813d4e723498aa51cb53173f9f4ba.png

b946fc091ab344f68b29ea7177c073b0.png

f310c052b21c40c5b3e0376364ea1ba3.png

执行该这条查询时,首先评估内查询或者子查询,即获得lettuce的unit_price,把结果传给外查询

(前面章节中可以在SELECT、FROM、WHERE中编写子查询)

 

 

练习:

63950552f9624d9b9689566254e70562.png

65dfd8d560a6435fa35d57311678f885.png

d6afa3aee7a44256bc91c4ae2b129a2a.png

 

 

3、THE IN OPERATOR——IN运算符

写一张可以返回一张有多列表的查询

4a77af69919f416da4b2ac4516374bb8.png

找到order_items表内所有产品;再写一段查询返回不在这张表里的产品

9e8619f586cb4ae48264a7cb85be6b83.png

1800adb2685d4d1eb88ea6dc060a15cc.png

 

练习:

49b18807c046460a88a70495cbc31e71.png

4245585a20b649bbb9898f9c4844908a.png

dd286aededaf43c1bc8058a496ab4205.png

 

 

4、SUBQUERIES VS JOINS——子查询VS连接

不用子查询,而使用连接来写,如何操作

e6f1e9f501e74251a33a257ea5a556f6.png

以上例子如果不用子查询,而使用连接来写,如何操作

376f5b6412e948c9982a037126be2152.png

选择所有客户,用invoices表连接这些客户

使用内连接,只会获取所有发票的客户;使用外连接(LEFT JOIN)会获取所有客户,不论是否有发票

 

使用子查询还是连接取决于:表现、可读性

如果执行时间一致,应该选择最易读的查询

 

如上例子,第一个查询更直观,和要解决的问题步调更一致,目的是找没有发票的客户(NOT IN),LEFT JOIN和问题有些摩擦(并不总是)

有时添加子查询会使一个查询太过复杂,那时则适合用连接

※永远要花心思在代码的可读性上

 

练习:

07e3a3a5b5c0497191570431b0ad5b50.png

f389f80a2f254b26b67e3a8cdce0fb3e.png 45fdf783984a49bc96c1f5b37c5e813e.png

6a685b21a7c2496e992c35d1fbf97cfe.png

显然第二种更有意义,因为customers、orders、order_items之间有一种自然的关联

 

 

5、THE ALL KEYWORD——ALL关键字

ab7aa714bc3c4c35b5b76b65c1351a3a.png

一般方法:对MAX(invoice_total)单一值比较

09fba4bc21bc4264a1d01e62121fee88.png

ALL关键字:对(invoice_total)列值中最高的进行比较

af37f0a3d3d749a48b76b7870536643e.png

两种皆可使用看个人习惯(第二种能直观反映问题所在)

 

 

6、THE ANY KEYWORD——ANY关键字

14b469a3a5854ef787c18b62f5ee8fd1.png

2005d5c5a58b4d40950fb1c25e92431e.png 174c0351df2443369555caf8611f4c23.png

以上条件返回client信息

9580d2d801fe40dc8578faf357804982.png 510b0ab2d17e4c149fafa2925c141171.png

52cb331329c54f53af8284336da12fdc.png

client_id=ANY:client_id等于这段查询返回的值里的任何一个,那位客户就会被返回最终结果

※=ANY和IN运算符等效

 

 

7、CORRELATED SUBQUERIES——相关子查询

a5770f7413fe4b7ba07a6df17c670086.png

40baf9357e684ae8a3d0067dcb6491d0.png

表中含有员工工资、所在部门、部门1有4位员工,找出这些员工的平均工资,只返回平均线以上的员工;同样找部门2的员工平均工资、平均线以上

所以这里的平均数不是固定不变的

伪代码:长得像代码却不是代码

d0e175dbb6ed4758ba46f80b32109c76.png

518fb16d3cc24470a1cd205e0b8bcd2a.png

①如何筛选一个部门的员工:

先给表格起别名employees e,

难点在WHERE office_id=e.office_id:内外查询都使用employees表,为了获取同各部门的员工,在office_id加上前缀

②MySQL执行以上查询逻辑是:

定位employees表,对每位员工执行子查询,计算同一个部门员工

(office_id=e.office_id)的平均工资

如果该员工的工资高于平均值,将被返回到最终结果里

第二条记录也会计算所有同一部门员工的平均工资,

 

因为子查询和外查询存在相关性,内查询中引用了外查询里出现的别名

e.office_id,

所以子查询会在住查询每一行的层面执行

也因此,相关子查询执行得比较慢,数据越多查询更费力,占用更多的存储

 

练习:

b5dff2532366439fb2ae8fe65439d9e8.png

70f4c989b26845d6bafa174ded1946ba.png

发票表中,对每位客户都要找到平均发票额,也就是invoice_toal列的平均,只返回有更高总额的发票,并对每个顾客都重复如上操作,此处用到相关子查询,因没有整张表采用一样的平均值

6d2a73058d5946dab091a7bedd3d86ab.png

21c5573ea2be4225849bc76435856dbd.png

 

8、THE EXISTS OPERATOR——EXISTS运算符

4f1eab87ec624b75b0ff3408054fbc43.png

用上面学过的方法:①IN运算符;②连接

01f0ee27ab0f40159648d163fd77393f.png c5d99e95878042e38e7bd0e07b1ef3ab.png

使用EXISTS

43726b22914f4203b489feaedb07cad6.png

使用相关子查询把内外连接关联,在子查询中使用client_id,然而主查询WHERE子句没有引用列,而是用EXISTS运算符查看invoices表中是否有符合这个条件的行

MySQL逻辑:对clients表中每个客户都检查是否存在一条符合这个条件的记录

 

IN运算符和EXISTS运算符方法的区别:

IN运算符:MySQL执行子句后结果返回到WHERE子句,如果数据巨大,会妨碍最佳性能

EXISTS运算符:能提高效率,子查询没有给外查询返回一个结果,而是返回一个指令,说明子查询中是否有符合这个搜索条件的行

子查询返回TRUE指令,EXISTS运算符就会在最终结果里添加当前记录(当前客户)

 

练习:

1bf5781b61984b3e9d4a806f3d0148b5.png

             879dc65124be46159fef390c060dc59f.png

 

9、SUBQUERIES IN THE SELECT CLAUSE——SELECT子句中的子查询

604739bea9614517a00d3ffa781c56c2.png

c30fc4576fe5486e83c6451adcec2334.png

不能在表达中使用列的别名

 

练习:

bd08985cba63455ba21393a0b0c60dd1.png

92c2fe2c57904b27a4e1acb819586577.png

WHERE client_id = c.client_id,子查询就可返回每位顾客的总成交量

 

10、SUBQUERIES IN THE FROM CLAUSE——FROM子句中的子查询

8488eca21f914598bda1651add82576f.png

直接将上节的表当作是真实的一张表使用

在选择语句的FROM子句中使用子查询

当在FROM子句中使用子查询,需要给子查询一个别名(必选项),不管会不会使用到别名

8fb133b97b16448b94723444233b0439.png

870e98c0a7514b529765bdb7d953516c.png

暂无变化

 

 

eac9075ef1b249969c96224ed1451e1f.png

使用该表,并把空值去掉

还可以将这张表与其他表连接使用

 

 

在选择语句中的FROM子句中写子查询,会让主查询变得更复杂,仅限于简单的查询

一个更好的解决方案就是使用视图

5b6cf8b9d50a43188053a6cb7072033f.png

将这部分作为视图储存在数据库中,并将视图命名为sales_summary,可以大大简化查询

 

 

————TBC

 

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值