SQL基础-第7章 集合运算
2021/11/19 19:12:06
本文主要是介绍SQL基础-第7章 集合运算,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
7-1 表的加减法
什么是集合运算
集合运算,就是对满足同一规则的记录进行的加减等四则运算
表的加法——UNION
集合运算符会除去重复的记录。
-- 创建表Product2(商品2) CREATE TABLE Product2 (product_id CHAR(4) NOT NULL, product_name VARCHAR(100) NOT NULL, product_type VARCHAR(32) NOT NULL, sale_price INTEGER , purchase_price INTEGER , regist_date DATE , PRIMARY KEY (product_id)) DEFAULT CHARSET=utf8; -- 将数据插入到表Product2(商品2)中 START TRANSACTION; INSERT INTO Product2 VALUES ('0001', 'T恤衫' ,'衣服', 1000, 500, '2008-09-20'); INSERT INTO Product2 VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11'); INSERT INTO Product2 VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL); INSERT INTO Product2 VALUES ('0009', '手套', '衣服', 800, 500, NULL); INSERT INTO Product2 VALUES ('0010', '水壶', '厨房用具', 2000, 1700, '2009-09-20'); COMMIT; -- 使用UNION对表进行加法运算 SELECT product_id, product_name FROM Product UNION SELECT product_id, product_name FROM Product2;
集合运算的注意事项
- 作为运算对象的记录的列数必须相同
-- 列数不一致时会发生错误 SELECT product_id, product_name FROM Product UNION SELECT product_id, product_name, sale_price FROM Product2;
- 作为运算对象的记录中列的类型必须一致
-- 数据类型不一致时会发生错误 SELECT product_id, sale_price FROM Product UNION SELECT product_id, regist_date FROM Product2;
- 可以使用任何SELECT语句,但ORDER BY子句只能在最后使用一次
-- ORDER BY子句只在最后使用一次 SELECT product_id, product_name FROM Product WHERE product_type = '厨房用具' UNION SELECT product_id, product_name FROM Product2 WHERE product_type = '厨房用具' ORDER BY product_id;
包含重复行的集合运算——ALL选项
在集合运算符中使用ALL选项,可以保留重复行。
-- 保留重复行 SELECT product_id, product_name FROM Product UNION ALL SELECT product_id, product_name FROM Product2;
7-2 联结(以列为单位对表进行联结)
什么是联结
就是将其他表中的列添加过来,进行“添加列”的运算
内联结——INNER-JOIN
- 内联结要点—FROM子句
-- 进行联结时需要在FROM子句中使用多张表。 FROM ShopProduct AS SP INNER JOIN Product AS P
- 内联结要点--ON子句
-- 进行内联结时必须使用ON子句,并且要书写在FROM和WHERE之间。 ON SP.product_id = P.product_id;
- 内联结要点-—SELECT子句
-- 使用联结时SELECT子句中的列需要按照“<表的别名>.<列名>”的格式进行书写。 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
- 将两张表进行内联结 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price FROM ShopProduct AS SP INNER JOIN Product AS P ON SP.product_id = P.product_id; -- 内联结和WHERE子句结合使用 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price FROM ShopProduct AS SP INNER JOIN Product AS P ON SP.product_id = P.product_id WHERE SP.shop_id = '000A';
外联结——OUTER-JOIN
- 外联结要点-选取出单张表中全部的信息
- 外联结要点-每张表都是主表吗?
- 使用 LEFT 时 FROM 子句中写在左侧的表是主表
- 使用 RIGHT 时右侧的表是主表
-- 将两张表进行外联结 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price FROM ShopProduct AS SP RIGHT OUTER JOIN Product AS P ON SP.product_id = P.product_id; -- 改写后外联结的结果完全相同 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price FROM Product AS P LEFT OUTER JOIN ShopProduct AS SP ON SP.product_id = P.product_id;
3张以上的表的联结
-- 创建InventoryProduct表并向其中插入数据 -- DDL :创建表 CREATE TABLE InventoryProduct ( inventory_id CHAR(4) NOT NULL, product_id CHAR(4) NOT NULL, inventory_quantity INTEGER NOT NULL, PRIMARY KEY (inventory_id, product_id)); -- DML :插入数据 START TRANSACTION; INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0001', 0); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0002', 120); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0003', 200); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0004', 3); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0005', 0); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0006', 99); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0007', 999); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P001', '0008', 200); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0001', 10); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0002', 25); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0003', 34); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0004', 19); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0005', 99); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0006', 0); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0007', 0); INSERT INTO InventoryProduct (inventory_id, product_id, inventory_quantity) VALUES ('P002', '0008', 18); COMMIT; -- 对3张表进行内联结 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price, IP.inventory_quantity FROM ShopProduct AS SP INNER JOIN Product AS P ON SP.product_id = P.product_id INNER JOIN InventoryProduct AS IP ON SP.product_id = IP.product_id WHERE IP.inventory_id = 'P001';
交叉联结——CROSS-JOIN 笛卡儿积
-- 将两张表进行交叉联结 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name FROM ShopProduct AS SP CROSS JOIN Product AS P;
联结的特定语法和过时语法
-- 使用过时语法的内联结 SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price FROM ShopProduct SP, Product P WHERE SP.product_id = P.product_id AND SP.shop_id = '000A'; -- DDL :创建表 CREATE TABLE Skills (skill VARCHAR(32), PRIMARY KEY(skill)); CREATE TABLE EmpSkills (emp VARCHAR(32), skill VARCHAR(32), PRIMARY KEY(emp, skill)) DEFAULT CHARSET=utf8; -- DML :插入数据 START TRANSACTION; INSERT INTO Skills VALUES('Oracle'); INSERT INTO Skills VALUES('UNIX'); INSERT INTO Skills VALUES('Java'); INSERT INTO EmpSkills VALUES('相田', 'Oracle'); INSERT INTO EmpSkills VALUES('相田', 'UNIX'); INSERT INTO EmpSkills VALUES('相田', 'Java'); INSERT INTO EmpSkills VALUES('相田', 'C#'); INSERT INTO EmpSkills VALUES('神崎', 'Oracle'); INSERT INTO EmpSkills VALUES('神崎', 'UNIX'); INSERT INTO EmpSkills VALUES('神崎', 'Java'); INSERT INTO EmpSkills VALUES('平井', 'UNIX'); INSERT INTO EmpSkills VALUES('平井', 'Oracle'); INSERT INTO EmpSkills VALUES('平井', 'PHP'); INSERT INTO EmpSkills VALUES('平井', 'Perl'); INSERT INTO EmpSkills VALUES('平井', 'C++'); INSERT INTO EmpSkills VALUES('若田部', 'Perl'); INSERT INTO EmpSkills VALUES('渡来', 'Oracle'); COMMIT; -- 选取出掌握所有3个领域的技术的员工 SELECT DISTINCT emp FROM EmpSkills ES1 WHERE NOT EXISTS (SELECT skill FROM Skills EXCEPT SELECT skill FROM EmpSkills ES2 WHERE EP1.emp = ES2.emp);
练习题
7.1 请说出下述 SELECT 语句的结果。
-- 使用本章中的Product表 SELECT * FROM Product UNION SELECT * FROM Product INTERSECT SELECT * FROM Product ORDER BY product_id;
会将 Product 表中的 8 行记录原封不动地选取出来。
7.2 7-2 节的代码清单 7-11 中列举的外联结的结果中,高压锅和圆珠笔 2 条 记录的商店编号( shop_id)和商店名称( shop_name)都是 NULL。
请使用字符串“不确定”替换其中的 NULL。期望结果如下所示。
执行结果
shop_id | shop_name | product_id | product_name | sale_price |
---|---|---|---|---|
000A | 东京 | 0002 | 打孔器 | 500 |
000A | 东京 | 0003 | 运动T恤 | 4000 |
000A | 东京 | 0001 | T恤衫 | 1000 |
000B | 名古屋 | 0006 | 叉子 | 500 |
000B | 名古屋 | 0002 | 打孔器 | 500 |
000B | 名古屋 | 0003 | 运动T恤 | 4000 |
000B | 名古屋 | 0004 | 菜刀 | 3000 |
000B | 名古屋 | 0007 | 擦菜板 | 880 |
000C | 大阪 | 0006 | 叉子 | 500 |
000C | 大阪 | 0007 | 擦菜板 | 880 |
000C | 大阪 | 0003 | 运动T恤 | 4000 |
000C | 大阪 | 0004 | 菜刀 | 3000 |
000D | 福冈 | 0001 | T恤衫 | 1000 |
不确定 | 不确定 | 0005 | 高压锅 | 6800 |
不确定 | 不确定 | 0008 | 圆珠笔 | 100 |
将商店编号和商店名称输出为"不确定"
SELECT COALESCE(s.shop_id, '不确定') as shop_id, COALESCE(s.shop_name, '不确定') as shop_name, p.product_id, p.product_name, p.sale_price FROM ShopProduct s RIGHT OUTER JOIN Product p ON s.product_id = p.product_id;
这篇关于SQL基础-第7章 集合运算的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南