多表查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多表查询相关的知识,希望对你有一定的参考价值。

/*
创建1对多关系的表
主表:商品分类表 category
从表:商品表 products
products使用category中的主键作为外键
*/
-- 创建商品分类表 category:分类主键,分类名称
CREATE TABLE category(
  cid INT PRIMARY KEY AUTO_INCREMENT,
  cname VARCHAR(20)
);

-- 往category中插入测试数据
INSERT INTO category(cname) VALUES(‘服装‘),(‘家电‘),(‘玩具‘),(‘鞋帽‘);

-- 创建商品表products:商品主键,商品名称,商品价钱,商品分类表的主键(外键)
CREATE TABLE products(
  pid INT PRIMARY KEY AUTO_INCREMENT,
  pname VARCHAR(20),
  price DOUBLE,
  category_cid INT
);

/*
把从表中的字段category_cid设置为主表的外键
格式:
alter table 从表 add [constraint] [外键名称] foreign key (从表外键字段名)
references 主表 (主表的主键);
*/
ALTER TABLE products ADD CONSTRAINT cid_FK FOREIGN KEY(category_cid)
REFERENCES category(cid);

-- 往从表products中添加数据,外键使用主表的主键
INSERT INTO products(pname,price,category_cid) VALUES(‘羽绒服‘,300,1);
INSERT INTO products(pname,price,category_cid) VALUES(‘军大衣‘,100,1);
INSERT INTO products(pname,price,category_cid) VALUES(‘手电‘,10,2);
INSERT INTO products(pname,price,category_cid) VALUES(‘超级飞侠‘,69,3);
INSERT INTO products(pname,price,category_cid) VALUES(‘高跟鞋‘,2000,4);

-- 往从表products中添加数据,使用主表中不存在的主键
INSERT INTO products(pname,price,category_cid) VALUES(‘冰箱‘,1800,5);

-- 删除category表主键为4的数据
-- 无法直接删除主表已经被从表使用的数据,必须先删除从表的数据
DELETE FROM products WHERE pid=5;
DELETE FROM category WHERE cid=4;

-- 向商品表添加普通数据,没有外键数据,默认为null
INSERT INTO products(pname,price) VALUES(‘冰箱‘,1800);


/*
多对多的关系
主表:商品表,订单表
中间表:使用商品表的主键(外键),使用订单表的主键(外键)
*/
-- 创建订单表orders:订单主键,商品的总金额
CREATE TABLE orders(
  oid INT PRIMARY KEY AUTO_INCREMENT,
  totalprice DOUBLE
);

-- 往订单表中添加数据
INSERT INTO orders(totalprice) VALUES(310),(169),(2400);

-- 创建中间表orderitem:使用商品表的主键(外键),使用订单表的主键(外键)
CREATE TABLE orderitem(
  pid INT,
  oid INT
);

-- 添加中间表字段cid为products中的主键的外键
ALTER TABLE orderitem ADD FOREIGN KEY(pid) REFERENCES products(pid);

-- 添加中间表字段oid为orders中的主键的外键
ALTER TABLE orderitem ADD FOREIGN KEY(oid) REFERENCES orders(oid);

-- 往中间表中添加数据
INSERT INTO orderitem(pid,oid)VALUES(1,1),(3,1),(2,2),(4,2),(1,3),(2,3),(5,3);
-- 往中间表中添加数据 pid不存在的
INSERT INTO orderitem(pid,oid)VALUES(6,1);
-- 往中间表中添加数据 oid不存在的
INSERT INTO orderitem(pid,oid)VALUES(1,4);

-- 删除products中id为4的数据(中间表在使用,不能直接删除)
DELETE FROM products WHERE pid=4;

-- 中间表数据可以直接删除
DELETE FROM orderitem WHERE pid =1 AND oid=1;

多表查询
最少有2张以上的表一起查询

交叉连接查询:查询出来的数据是错误的(笛卡尔积)

内连接:[inner join on ]


隐式内连接:省略inner join on
select * from 表A ,表B where 表A.主键=表B.外键
显示:写出inner join on
select * from 表A inner join 表B on 表A.主键=表B.外键


外链接:
左外连接(以左边的表为主):left [outer] join on
select * from 表A left [outer] join 表B on 表A.主键=表B.外键
右外连接(以右边的表为主):right [outer] join on
select * from 表A right [outer] join 表B on 表A.主键=表B.外键


子查询:
一条sql语句的查询结果,作为另一条sql语句的(条件,另一张表,结果)
select * from 表A where 字段 = (select * from 表B)
SELECT * FROM category,products;

-- 隐式内连接: 省略inner join on
SELECT * FROM category,products WHERE category.cid=products.category_id;

-- 简化隐式内连接,使用关键字as给表起别名
SELECT * FROM category c,products p WHERE c.cid = p.category_id;

-- 显示内连接: 写出inner join on
SELECT * FROM category c INNER JOIN products p ON c.cid = p.category_id;

-- 只要家电和化妆品(显示内连接,后边可以写where条件)
SELECT * FROM category c INNER JOIN products p ON c.cid = p.category_id
WHERE c.cid <> 2;

-- 只要家电和化妆品(隐式内连接,多个条件使用逻辑运算符连接在一起)
SELECT * FROM category c,products p WHERE c.cid = p.category_id AND c.cid <> 2;

-- 查询那些商品已经上架(显示)
SELECT * FROM category c INNER JOIN products p ON c.cid = p.category_id WHERE p.flag=1;

-- 查询那些商品已经上架(隐式)
SELECT * FROM category c ,products p WHERE c.cid = p.category_id AND p.flag=1;


-- 左外连接(以左边的表为主):left [outer] join on
-- 以左边的表为主,左边有的数据,右边没有,使用null显示
SELECT * FROM category c LEFT OUTER JOIN products p ON c.cid = p.category_id;


-- 右外连接(以右边的表为主):right [outer] join on
-- 以右边为主,右边没有的数据,左边不能显示出来
SELECT * FROM category c RIGHT OUTER JOIN products p ON c.cid=p.category_id;

-- 左外连接(以左边的表为主):left [outer] join on
SELECT * FROM products p LEFT OUTER JOIN category c ON c.cid = p.category_id;

-- 统计每类商品的数量
SELECT cname,COUNT(category_id) FROM category c LEFT OUTER JOIN products p
ON c.cid=p.category_id
GROUP BY cname;


-- 子查询: 一条sql语句的查询结果,作为另外一条sql语句的(条件,另一张表,结果)
-- 使用隐式内连接,查询“化妆品”商品详情
SELECT * FROM category c,products p WHERE c.cid=p.category_id AND c.cname=‘化妆品‘

-- 使用子查询,查询“化妆品”商品详情
SELECT * FROM products WHERE category_id=3;
SELECT * FROM products WHERE category_id =
(SELECT cid FROM category WHERE cname=‘化妆品‘);

-- 一个sql语句的结果作为另外一个sql语句的另一张表
SELECT * FROM products p,
(SELECT * FROM category WHERE cname=‘化妆品‘)c
WHERE p.category_id = c.cid;

-- 查询“化妆品”和“家电”两个分类上架商品详情
-- 使用条件子查询
SELECT * FROM products WHERE category_id IN
(SELECT cid FROM category WHERE cname=‘化妆品‘ OR cname=‘家电‘);

-- 使用另外一张表作为子查询
SELECT * FROM products p,mybase2mysqlmysqlmybase2category
(SELECT * FROM category WHERE cname=‘化妆品‘ OR cname=‘家电‘)c
WHERE p.category_id = c.cid;

以上是关于多表查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL-04-笔记

Oracle笔记 多表查询

SQL语句 - 多表查询使用详细介绍

多表查询_左连接多表操作_子查询

多表查询

MySQL 如何多表查询