sql 集合的差 mysql_SQL集合运算

本专栏与大家分享小白学SQL的全过程,记录学习中遇到的难题与相应解决方法,希望能和大家共勉成长。才疏学浅文章多有错漏,还望大家多多指导,谢谢!

资料来源:DataWhale组队学习

结合运算并,交和差-UNION,INTERSECT和EXCEPT

表的加法—UNION

**练习题:**假设连锁店想要增加毛利率超过 50%或者售价低于 800 的货物的存货量, 请使用 UNION 对分别满足上述两个条件的商品的查询结果求并集.7325a08b263c92b43f4c36c359d3c304.png

练习题:

找出 product 和 product2 中售价高于 500 的商品的基本信息.

Error Code: 1052. Column 'sale_price' in where clause is ambiguousc4b45e1d58f0cb2d58a1253a72ddfdb3.png

不去重 UNION ALL

练习题:

商店决定对product表中利润低于50%和售价低于1000的商品提价, 请使用UNION ALL 语句将分别满足上述两个条件的结果取并集. 查询结果类似下表:3f61de6eacf80f41219abc8c0e830d2a.png

76ee228f5b729c6cf410ebe2c097ec48.png

bag模型bag 里面允许存在重复元素, 如果同一个元素被加入多次, 则袋子里就有多个该元素.

UNION ALL, EXCEPT ALL 都是按出现次数进行减法, 使用bag模型进行运算.

对于两个 bag, 他们的并运算会按照:1.该元素是否至少在一个 bag 里出现过, 2.该元素在两个 bag 中的最大出现次数这两个方面来进行计算. 因此对于 A = {1,1,1,2,3,5,7}, B = {1,1,2,2,4,6,8} 两个 bag, 它们的并就等于 {1,1,1,2,2,3,4,5,6,7,8}.

对于两个 bag, 他们的交运算会按照:1.该元素是否同时属于两个 bag, 2.该元素在两个 bag 中的最小出现次数这两个方面来进行计算. 因此对于 A = {1,1,1,2,3,5,7}, B = {1,1,2,2,4,6,8} 两个 bag, 它们的交运算结果就等于 {1,1,2}.

对于两个 bag, 他们的差运算会按照:1.该元素是否属于作为被减数的 bag,2.该元素在两个 bag 中的出现次数,对于 A = {1,1,1,2,3,5,7}, B = {1,1,2,2,4,6,8} 两个 bag, 它们的差就等于 {1,3,5,7}.

隐式类型转换来将两个类型不同的列放在一列里显示, 例如字符串和数值类型:

SELECT product_id, product_name, '1'

FROM product

UNION

SELECT product_id, product_name,sale_price

FROM product2;

练习题:

使用 SYSDATE()函数可以返回当前日期时间, 是一个日期时间类型的数据, 试测试该数据类型和数值,字符串等类型的兼容性.857bf3160d0b6b37538c06494d3cd686.png

Error 1064语法错误:

截止到 MySQL 8.0 版本, MySQL 仍然不支持 INTERSECT 操作.

MySQL 8.0 还不支持 表的减法运算符 EXCEPT. 不过, 借助第六章学过的NOT IN 谓词, 我们同样可以实现表的减法.

练习题**:**

找出只存在于product表但不存在于product2表的商品.

-- 使用 IN 子句的实现方法

SELECT *

FROM product

WHERE product_id NOT IN (SELECT product_id

FROM product2)

练习题:

使用NOT谓词进行集合的减法运算, 求出product表中, 售价高于2000,但利润低于30%的商品, 结果应该如下表所示.bd7b0270863614850fc9f478596e4ed5.png

SELECT*

FROMproduct

WHEREsale_price >2000ANDproduct_idNOTIN(SELECTproduct_id

FROMproduct

WHEREsale_price>1.3*purchase_price);

练习题:

****使用AND谓词查找product表中利润率高于50%,并且售价低于1500的商品,查询结果如下所示.57ef3564d7cb2f77d492c01bbe4f9efe.png

8036d53c93fbfba531dde7bb811fbe2a.png

对称差两个集合A,B的对称差是指那些仅属于A或仅属于B的元素构成的集合

两个集合的对称差等于 A-B并上B-Aeb3addf21e6d4e2ede221d78f57b07a3.png

连结(join)集合运算的特征就是以行方向为单位进行操作,会导致记录行数的增减

使用函数或者 CASE表达式等列运算, 可以增加列的数量, 但仍然只能从一张表中获得一些"引申列", 本质并不能提供更多的信息.

期望得到的数据往往会分散在不同的表之中, 这时候就需要使用连结了

使用关联子查询也可以从其他表获取信息, 但连结更适合从多张表获取信息.f804054fd6b52db0aab21fe2eb4b0b5c.png

内连结(INNER JOIN)

内连结的语法格式是:

-- 内连结

FROM INNER JOIN ON

找出一个类似于"轴"或者"桥梁"的公共列, 将两张表用这个列连结起来. 这就是连结运算所要作的事情.

子查询结果是虚拟的表,因此INNER JOIN可接子查询分解任务be90be9e740122581c38f47dab42aa25.png

结合 GROUP BY 子句使用内连结, 需要根据分组列位于哪个表区别对待

最简单是在内连结之前就使用 GROUP BY 子句

如果分组列和被聚合的列不在同一张表, 且二者都未被用于连结两张表, 则只能先连结, 再聚合

在实践中, 一定要按照易于让自己理解的思路去分层次写代码, 而不要花费很长世间写出一个效率可能更高但自己和他人理解起来难度更高的代码

自然连结并不是区别于内连结和外连结的第三种连结, 它其实是内连结的一种特例–当两个表进行自然连结时, 会按照两个表中都包含的列名来进行等值内连结, 此时无需使用 ON 来指定连接条件.

使用自然连结还可以求出两张表或子查询的公共部分

SELECT*FROMproductNATURALJOINproduct2b247ca2b352bda93e7de16c14e0e9b7a.png

在自然连结进行行数据比较时, 实际上是在逐字段进行等值连结“=”, 两个缺失值用等号进行比较, 结果不为真. 而连结只会返回对连结条件返回为真的那些行。

如果我们将查询语句进行修改:

SELECT *

FROM (SELECT product_id, product_name

FROM product ) AS A

NATURAL JOIN

(SELECT product_id, product_name

FROM product2) AS B;

那就可以得到正确的结果了:ae25b073422ee0253a92f1336b5347f5.png

外连结

内连结会丢弃两张表中不满足 ON 条件的行,和内连结相对的就是外连结. 外连结会根据外连结的种类有选择地保留无法匹配到的行.

按照保留的行位于哪张表,外连结有三种形式: 左连结, 右连结和全外连结

左连结会保存左表中无法按照 ON 子句匹配到的行, 此时对应右表的行均为缺失值; 右连结则会保存右表中无法按照 ON 子句匹配到的行, 此时对应左表的行均为缺失值; 而全外连结则会同时保存两个表中无法按照 ON子句匹配到的行, 相应的另一张表中的行用缺失值填充.

三种外连结的对应语法分别为:

-- 左连结

FROM LEFT  OUTER JOIN ON

-- 右连结

FROM RIGHT OUTER JOIN ON

-- 全外连结

FROM FULL  OUTER JOIN ON

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值