1. 知识点简单梳理
1.1 UNION和UNION ALL之间的区别
UNION会对结果集进行合并和去重
这种去重不仅会去掉两个结果集相互重复的, 还会去掉一个结果集中的重复行;
UNION ALL保留重复行
1.2 隐式类型转换
通常来说, 我们会把类型完全一致, 并且代表相同属性的列使用 UNION 合并到一起显示,。但有时候, 即使数据类型不完全相同, 也会通过隐式类型转换来将两个类型不同的列放在一列里显示,只能临时这么干,因为这样会导致程序可读性差,且依赖数据库的隐式转换规则。如果数据库升级,则程序可能无法正确执行。
SELECT 1+'1'; 结果:2
SELECT CONCAT('北京',2008); 结果:北京2008
SELECT '北京' + 2008; 结果:2008
SELECT 'HELLO ' + 'WORLD!'; 结果:0
1.3 SYSDATE()获取当前系统日期时间
2021-02-21 10:00:00
1.4 INTERSECT,返回结果集的交集
注意:mysql 8.0版本已取消该功能
1.5 EXCEPT,返回结果集的差集(和not in功能类似)
在逻辑上先删除两个输入多集中的重复行,把多集变成集合,然后返回只在第一个集合中出现,在第二个集合中不出现的所有行。可以看下面示意图
注意:mysql 8.0版本已取消该功能
1.6 对称差
两个集合A,B的对称差是指那些仅属于A或仅属于B的元素构成的集合
方法:
使用 NOT IN 实现两个表的差集.
-- 使用 NOT IN 实现两个表的差集
SELECT *
FROM product
WHERE product_id NOT IN (SELECT product_id FROM product2)
UNION
SELECT *
FROM product2
WHERE product_id NOT IN (SELECT product_id FROM product)
1.7 自然连接(NATURAL JOIN)
内连结的一种特例–当两个表进行自然连结时, 会按照两个表中都包含的列名来进行等值内连结, 此时无需使用 ON 来指定连接条件。可以求出两张表或子查询的公共部分。
语法:
SELECT * FROM shopproduct NATURAL JOIN product
2. 练习题
2.1 找出 product 和 product2 中售价高于 500 的商品的基本信息。
SELECT *
FROM Product
WHERE Product2.sale_price > 500
UNION
SELECT *
FROM Product2
WHERE Product2.sale_price > 500
2.2 借助对称差的实现方式, 求product和product2的交集。
SELECT * FROM Product
WHERE product_id not in
(SELECT Product2.product_id FROM Product2)
UNION
SELECT * FROM Product2
WHERE product_id not in
(SELECT Product.product_id FROM Product)
2.3 每类商品中售价最高的商品都在哪些商店有售 ?
SELECT S.shop_name ,P.product_type ,P.sale_price
FROM Product AS P
INNER JOIN ShopProduct AS S
ON P.product_id = S.product_id
GROUP BY P.product_type
ORDER BY P.sale_price desc
limit 1
2.4 分别使用内连结和关联子查询每一类商品中售价最高的商品。
内连接:
SELECT p1.product_id, p1.product_name, p1.product_type, p1.sale_price, p2.max_sale_price
FROM product AS p1
INNER JOIN
(SELECT product_type, MAX(sale_price) AS max_sale_price
FROM product
GROUP BY product_type) AS p2
ON p1.product_type = p2.product_type
AND p1.sale_price = p2.max_sale_price;
关联子连接:
SELECT p1.product_id, p1.product_name, p1.product_type, p1.sale_price
FROM product AS p1
WHERE p1.sale_price = (SELECT MAX(sale_price) AS max_sale_price
FROM product AS p2
WHERE p1.product_type = p2.product_type
GROUP BY product_type);
外连接:
SELECT P1.product_id ,P1.product_name ,P2.sale_price ,COUNT(P2.sale_price) + 1 AS ranking
FROM Product AS P1
LEFT JOIN Prouduct AS P2
ON P1.sale_price > P2.sale_price
AND P1.product_type = P2.product_type
GROUP BY P1.product_type
ORDER BY ranking DESC
limit 1
2.5 用关联子查询实现:在product表中,取出 product_id, produc_name, slae_price, 并按照商品的售价从低到高进行排序、对售价进行累计求和。
SELECT product_id, product_name, sale_price,
(SELECT SUM(sale_price) FROM product AS P2
WHERE P1.sale_price >= P2.sale_price
AND P1.product_id <= P2.product_id) AS '累计销售价格'
FROM product AS P1
ORDER BY sale_price;
如果不指定关联子查询:
SELECT P1.product_id ,P1.product_name ,P2.sale_price ,SUM(P2.sale_price) AS '累计销售价格'
FROM Product AS P1
LEFT JOIN Prouduct AS P2
ON P1.sale_price >= P2.sale_price
AND P1.product_id != P2.product_id
GROUP BY P1.product_id ,P1.product_type
ORDER BY sale_price DESC