集合运算就是对满足同一规则的记录进行的加减等四则运算
准备工作:
创建新表Product2
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));
BEGIN TRANSACTION;
INSERT INTO Product2 VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2009-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;
初始化Product表
delete from Product;--清空Product表
begin transaction;
insert into Product values('0001','T恤衫','衣服',1000,500,'2009-09-20');
insert into Product values('0002','打孔器','办公用品',500,320,'2009-09-11');
insert into Product values('0003','运动T恤','衣服',4000,2800,null);
insert into Product values('0004','菜刀','厨房用具',3000,2800,'2009-09-20');
insert into Product values('0005','高压锅','厨房用具',6800,5000,'2009-01-15');
insert into Product values('0006','叉子','厨房用具',500,null,'2009-09-20');
insert into Product values('0007','擦菜板','厨房用具',880,790,'2008-04-28');
insert into Product values('0008','圆珠笔','办公用品',100,null,'2009-11-11');
commit;
表的加减法
1、表的加法—UNION(并集)
相当于数学集合中的并集运算
SELECT product_id, product_name
FROM Product
UNION
SELECT product_id, product_name
FROM Product2;
上述结果包含了两张表中的全部商品,去掉重复选项
2、包含重复行的集合运算——ALL选项
SELECT product_id, product_name
FROM Product
UNION ALL
SELECT product_id, product_name
FROM Product2;
在UNION后加一ALL选项,则会保留重复数据
3、选取两表中公共部分—INTERSECT(交集)
SELECT product_id, product_name
FROM Product
INTERSECT
SELECT product_id, product_name
FROM Product2
ORDER BY product_id;
4、记录的减法——EXCEPT(差集)
SELECT product_id, product_name
FROM Product
EXCEPT
SELECT product_id, product_name
FROM Product2
ORDER BY product_id;
结果中只包含Product表中记录除去Product2表中共同部分之后的剩余结果。
注意:
EXCEPT中:减数和被减数的位置不同,所得到的结果也不同
--从Product2的记录中删除Product的记录
SELECT product_id, product_name
FROM Product2
EXCEPT
SELECT product_id, product_name
FROM Product
ORDER BY product_id;
集合运算的注意事项:
- 作为运算对象的记录的列数必须相同,也就是说两个select语句选择的列数必须相同。
- 作为运算对象的记录中的列的类型必须一致。
- 可以使用任何SELECT语句,但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;--只能在最后使用
联结
联结,就是将其他表中的列添加进来,进行“添加列”的结合运算。
(集合运算是以行方向为单位进行操作:使用UNION会增加记录行数,而使用INTERSECT或者EXCEPT会减少记录行数)
1、内联结——INNER JOIN
适用情况: 当需要查询2张表中同时存在的数据(返回在两张表中所有正确关联的行);
内联结只能选取出同时存在于两张表中的数据。
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;
要点:
- 进行联结时需要在from子句中使用多张表
- ON子句是专门用来指定联结条件的,它能起到与WHERE相同的子句。进行内联结时必须使用ON子句,并且要书写在FROM和WHERE子句之间。
- 使用联结时SELECT子句中的列需要按照“<表的别名>.<列名>"的格式进行书写
内联结和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';
2、外联结——OUTER JOIN
外联结:选取出单张表中全部的信息
外联结分为左外联结(left outer join)和右外联结(right outer join)
左外联结(left outer join): 左边的表为主表, 取左边的表的全部,右边的表按条件,符合的显示,不符合则显示null
语法格式:
select <select list> from A left outer join B on A.id=B.id;
例子:
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
FROM ShopProduct AS SP LEFT OUTER JOIN Product AS P
ON SP.product_id = P.product_id;
右外联结(left outer join): 右边的表为主表,取右边的表的全部,左边的表按条件,符合的显示,不符合则显示null
语法:select from A right join B on A.id=B.id
例子:
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;
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:插入数据
BEGIN 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;
对三张表进行内联结
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price, IP.inventory_quantity
FROM ShopProduct SP INNER JOIN Product P
ON SP.product_id = P.product_id
INNER JOIN InventoryProduct IP
ON SP.product_id = IP.product_id
WHERE IP.inventory_id = 'S001';
4、交叉联结——CROSS JOIN
交叉连接:返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积
首先,先简单解释一下笛卡尔积:笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。
SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name
FROM ShopProduct AS SP CROSS JOIN Product AS P;
交叉联结,不经常使用