集合运算 union/except/intersect/inner join/right join

##################
##集合运算
##################

#####################1.表的加法 union(增加的是记录 竖直方向) 
use xscj;

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));

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'); 

select product_id,product_name from product
union
select product_id,product_name from product2;


-- 集合运算的注意事项 
# 1.作为运算对象的记录的列数必须相同 
# 2.作为运算对象的记录的列的类型必须一致 (一定要不同类型的列是,可以使用类型转换函数cast)
# 3.可以使用任何select语句,但order by子句只能在最后使用一次 (where/group by /having)
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)

select product_id,product_name from product
union all
select product_id,product_name from product2;

#########################选取交集  intersect/intersect all
-- mysql可能不支持
select product_id,product_name from product
intersect all
select product_id,product_name from product2;



-- mysql不支持
#########################2.记录的减法 except
select product_id,product_name from product
except
select product_id,product_name from product2
order by product_id;


#########################3.联结(以列为单位对表进行联结,水平方向) 

########3.1内联结 Inner join
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;

-- 内联结要点1.from子句 
-- (from shopproduct as sp inner join product as p)这个才是来源 

-- 要点2:on 子句指定联结Key,必须在from和where之间 
-- on sp.product_id = p.product_id。联结条件可以用=/</>/<=/between等谓词

-- 要点3:在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';

#################3.2外联结 outer join
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;


-- 外联结要点1.选取单张表中全部的信息 
--           在实际的业务中,想要生成固定行数的单据是,就需要使用外联结 

-- 外联结要点2.每张表都是主表吗 right右主表 left左主表


###################3.3 三张以上的表的联结 
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));

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);

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';


################4.交叉联结 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';

-- Join新增知识点
SELECT companies.permalink AS companies_permalink,
       companies.name AS companies_name,
       acquisitions.company_permalink AS acquisitions_permalink,
       acquisitions.acquired_at AS acquired_date
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
   AND acquisitions.company_permalink != '/company/1000memories'
 ORDER BY 1
-- 注意on后面跟了and,你可以想象成where 但是和where不同的是:on...and是在连接之前发生的
-- 如果后面使用where则是在连接之后发生的

#union(并) 
#except(差) 
#intersect(交) 
#cross join(笛卡尔积) 
#关系除法 
CREATE TABLE Skills (
skill VARCHAR(32), 
PRIMARY KEY(skill)); 
CREATE TABLE EmpSkills (
emp   VARCHAR(32),  
skill VARCHAR(32), 
PRIMARY KEY(emp, skill));

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'); 

-- skills表是关系除法中的除数 Empskills表示关系除法中的被除数 
#选取掌握了skills表中所有三个领域的emp员工
select distinct emp from empskills esl
where not exists (select skill from skills 
                 except select skill from empskills es2
                 where es1.emp = es2.emp); -- es1.emp=es2.emp代表就对这一个特定的人选取他的所有技能 
-- 三个skill减去每个人的skill,如果大于零(即存在啥东西)就代表没有拥有全部的技能 
-- 如果没有东西就代表拥有全部技能 
-- 注意差集,前面的集合作为标准!!!! 
                 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值