《sql进阶教程》之用 SQL 进行集合运算
本文是《sql进阶教程》阅读笔记,感兴趣可以阅读该书对应章节,这本适合有一定sql基础的同学阅读。另外作者《sql基础教程》也值得一看
集合运算的几个注意事项
UNION ALL
和UNION
的区别除了运算结果以外,这两种用法还有一个不同。集合运算符为了排除掉重复行,默认地会发生排序,而加上可选项 ALL 之后,就不会再排序,所以性能会有提升。所以如果不关心结果是否存在重复行,或者确定结果里不会产生重复行,加上可选项 ALL 会更好些。
比较表和表
案例一、调查两张表是否是相等
名字不同但内容相同的两张表
tbl_A
key | col_1 | col_2 | col_3 |
---|---|---|---|
A | 2 | 3 | 4 |
B | 0 | 7 | 9 |
C | 5 | 1 | 6 |
tbl_B
key | col_1 | col_2 | col_3 |
---|---|---|---|
A | 2 | 3 | 4 |
B | 0 | 7 | 9 |
C | 5 | 1 | 6 |
-- 如果这个查询的结果与 tbl_A 及 tbl_B 的行数一致,则两张表是相等的
SELECT COUNT(*) AS row_cnt
FROM ( SELECT * FROM tbl_A
UNION SELECT * FROM tbl_B
) TMP;
-- 输出结果为3
寻找相等的子集
这里使用的表示“供应商 - 零件”关系的表作为示例数据:要求的是,经营的零件在种类数和种类上都完全相同的供应商组合。答案是
A-C
和 B-D
这两组
A和 E 虽然经营的零件种类数都是 3,但是零件的种类却不完全相同,所以不符合要求。F 则在种类数和种类上跟其他供应商都不相同,所以也不考虑。
-- 生成供应商的全部组合
SELECT SP1.sup AS s1, SP2.sup AS s2
FROM SupParts SP1, SupParts SP2
WHERE SP1.sup < SP2.sup
GROUP BY SP1.sup, SP2.sup;
(A ⊆ B)且(A ⊇ B)=>(A = B)。这个公式等价于下面两个条件。
- 条件 1:两个供应商都经营同种类型的零件
- 条件 2:两个供应商经营的零件种类数相同(即存在一一映射)
SELECT SP1.sup AS s1, SP2.sup AS s2
FROM SupParts SP1, SupParts SP2
WHERE SP1.sup < SP2.sup -- 生成供应商的全部组合
AND SP1.part = SP2.part -- 条件1 :经营同种类型的零件
GROUP BY SP1.sup, SP2.sup
HAVING COUNT(*) = (SELECT COUNT(*) -- 条件2 :经营的零件种类数相同
FROM SupParts SP3
WHERE SP3.sup = SP1.sup)
AND COUNT(*) = (SELECT COUNT(*)
FROM SupParts SP4
WHERE SP4.sup = SP2.sup);
补充:统计某一个记录(某些字段)出现在数据库中多次
场景:统计表中同一个电话号被多个人使用的情况。
SELECT COUNT(userid) AS num,phonenumber
FROM users GROUP BY phonenumber HAVING count(userid) > 1;
通过这种方式,可以统计出一些脏数据。