多表查询数据准备
-- 创建db4数据库
CREATE DATABASE db4;
-- 使用db4数据库
USE db4;
-- 创建user表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT, -- 用户id
NAME VARCHAR(20), -- 用户姓名
age INT -- 用户年龄
);
-- 添加数据
INSERT INTO USER VALUES (1,'张三',23);
INSERT INTO USER VALUES (2,'李四',24);
INSERT INTO USER VALUES (3,'王五',25);
INSERT INTO USER VALUES (4,'赵六',26);
-- 订单表
CREATE TABLE orderlist(
id INT PRIMARY KEY AUTO_INCREMENT, -- 订单id
number VARCHAR(30), -- 订单编号
uid INT, -- 外键字段
CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id)
);
-- 添加数据
INSERT INTO orderlist VALUES (1,'hm001',1);
INSERT INTO orderlist VALUES (2,'hm002',1);
INSERT INTO orderlist VALUES (3,'hm003',2);
INSERT INTO orderlist VALUES (4,'hm004',2);
INSERT INTO orderlist VALUES (5,'hm005',3);
INSERT INTO orderlist VALUES (6,'hm006',3);
INSERT INTO orderlist VALUES (7,'hm007',NULL);
-- 商品分类表
CREATE TABLE category(
id INT PRIMARY KEY AUTO_INCREMENT, -- 商品分类id
NAME VARCHAR(10) -- 商品分类名称
);
-- 添加数据
INSERT INTO category VALUES (1,'手机数码');
INSERT INTO category VALUES (2,'电脑办公');
INSERT INTO category VALUES (3,'烟酒茶糖');
INSERT INTO category VALUES (4,'鞋靴箱包');
-- 商品表
CREATE TABLE product(
id INT PRIMARY KEY AUTO_INCREMENT, -- 商品id
NAME VARCHAR(30), -- 商品名称
cid INT, -- 外键字段
CONSTRAINT cp_fk1 FOREIGN KEY (cid) REFERENCES category(id)
);
-- 添加数据
INSERT INTO product VALUES (1,'华为手机',1);
INSERT INTO product VALUES (2,'小米手机',1);
INSERT INTO product VALUES (3,'联想电脑',2);
INSERT INTO product VALUES (4,'苹果电脑',2);
INSERT INTO product VALUES (5,'中华香烟',3);
INSERT INTO product VALUES (6,'玉溪香烟',3);
INSERT INTO product VALUES (7,'计生用品',NULL);
-- 中间表
CREATE TABLE us_pro(
upid INT PRIMARY KEY AUTO_INCREMENT, -- 中间表id
uid INT, -- 外键字段。需要和用户表的主键产生关联
pid INT, -- 外键字段。需要和商品表的主键产生关联
CONSTRAINT up_fk1 FOREIGN KEY (uid) REFERENCES USER(id),
CONSTRAINT up_fk2 FOREIGN KEY (pid) REFERENCES product(id)
);
-- 添加数据
INSERT INTO us_pro VALUES (NULL,1,1);
INSERT INTO us_pro VALUES (NULL,1,2);
INSERT INTO us_pro VALUES (NULL,1,3);
INSERT INTO us_pro VALUES (NULL,1,4);
INSERT INTO us_pro VALUES (NULL,1,5);
INSERT INTO us_pro VALUES (NULL,1,6);
INSERT INTO us_pro VALUES (NULL,1,7);
INSERT INTO us_pro VALUES (NULL,2,1);
INSERT INTO us_pro VALUES (NULL,2,2);
INSERT INTO us_pro VALUES (NULL,2,3);
INSERT INTO us_pro VALUES (NULL,2,4);
INSERT INTO us_pro VALUES (NULL,2,5);
INSERT INTO us_pro VALUES (NULL,2,6);
INSERT INTO us_pro VALUES (NULL,2,7);
INSERT INTO us_pro VALUES (NULL,3,1);
INSERT INTO us_pro VALUES (NULL,3,2);
INSERT INTO us_pro VALUES (NULL,3,3);
INSERT INTO us_pro VALUES (NULL,3,4);
INSERT INTO us_pro VALUES (NULL,3,5);
INSERT INTO us_pro VALUES (NULL,3,6);
INSERT INTO us_pro VALUES (NULL,3,7);
INSERT INTO us_pro VALUES (NULL,4,1);
INSERT INTO us_pro VALUES (NULL,4,2);
INSERT INTO us_pro VALUES (NULL,4,3);
INSERT INTO us_pro VALUES (NULL,4,4);
INSERT INTO us_pro VALUES (NULL,4,5);
INSERT INTO us_pro VALUES (NULL,4,6);
INSERT INTO us_pro VALUES (NULL,4,7);
内连接查询
/*
显示内连接
标准语法:
SELECT 列名 FROM 表名1 [INNER] JOIN 表名2 ON 关联条件;
*/
-- 查询用户信息和对应的订单信息
SELECT
*
FROM
`USER`
JOIN orderlist ON `USER`.id = orderlist.uid
-- 查询用户信息和对应的订单信息,起别名
SELECT
*
FROM
`USER` u
INNER JOIN orderlist o ON u.id = o.uid
-- 查询用户姓名,年龄。和订单编号
SELECT
u.NAME,
u.age,
o.number
FROM
`USER` u
JOIN orderlist o ON u.id = o.uid
/*
隐式内连接
标准语法:
SELECT 列名 FROM 表名1,表名2 WHERE 关联条件;
*/
-- 查询用户姓名,年龄。和订单编号
SELECT
u.NAME,
u.age,
o.number
FROM
`USER` u,
orderlist o
WHERE
u.id = o.uid;
外连接查询
/*
左外连接
标准语法:
SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 条件;
*/
-- 查询所有用户信息,以及用户对应的订单信息
SELECT
u.*,
o.number
FROM
`USER` u
LEFT JOIN
orderlist o
ON
u.id=o.uid
/*
右外连接
标准语法:
SELECT 列名 FROM 表名1 RIGHT [OUTER] JOIN 表名2 ON 条件;
*/
-- 查询所有订单信息,以及订单所属的用户信息
SELECT
o.*,
u.name
FROM
`USER` u
RIGHT JOIN
orderlist o
ON
o.uid=u.id
子查询
/*
结果是单行单列的
标准语法:
SELECT 列名 FROM 表名 WHERE 列名=(SELECT 列名 FROM 表名 [WHERE 条件]);
*/
-- 查询年龄最高的用户姓名
select name ,age from `USER` where age=(SELECT MAX(age) FROM `USER`)
/*
结果是多行单列的
标准语法:
SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 条件]);
*/
-- 查询张三和李四的订单信息
-- 第一步 查询查询张三李四对应的id
select id FROM `USER` where name IN('张三','李四');
-- 第二步 将查询到的id作为一个条件
select * from orderlist where uid in(select id FROM `USER` where name IN('张三','李四'))
/*
结果是多行多列的
标准语法:
SELECT 列名 FROM 表名 [别名],(SELECT 列名 FROM 表名 [WHERE 条件]) [别名] [WHERE 条件];
*/
-- 查询订单表中id大于4的订单信息和所属用户信息
-- 第一步 先查询订单表中id>4的信息
SELECT * FROM orderlist where id>4;
-- 第二步 将查询出来的结果作为一张表 结合user表一起查询
select u.`NAME`,o.number FROM `USER` u,(SELECT * FROM orderlist where id>4) o where o.uid=u.id
自关联查询
-- 创建员工表
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT, -- 员工编号
NAME VARCHAR(20), -- 员工姓名
mgr INT, -- 上级编号
salary DOUBLE -- 员工工资
);
-- 添加数据
INSERT INTO employee VALUES (1001,'孙悟空',1005,9000.00),
(1002,'猪八戒',1005,8000.00),
(1003,'沙和尚',1005,8500.00),
(1004,'小白龙',1005,7900.00),
(1005,'唐僧',NULL,15000.00),
(1006,'武松',1009,7600.00),
(1007,'李逵',1009,7400.00),
(1008,'林冲',1009,8100.00),
(1009,'宋江',NULL,16000.00);
-- 查询所有员工的姓名及其直接上级的姓名,没有上级的员工也需要查询
/*
分析
员工信息 employee表
条件:employee.mgr = employee.id
查询左表的全部数据,和左右两张表有交集部分数据,左外连接
*/
SELECT
e1.id,
e1.name,
e1.mgr,
e2.id,
e2.name
FROM
employee e1
LEFT JOIN
employee e2
ON
e1.mgr=e2.id;
多表查询综合练习
-- 1.查询用户的编号、姓名、年龄。订单编号
/*
分析
用户的编号、姓名、年龄 user表 订单编号 orderlist表
条件:user.id=orderlist.uid
*/
SELECT
u.id, -- 用户编号
u.`NAME`, -- 用户姓名
u.age, -- 用户年龄
o.number -- 订单编号
FROM
`USER` u, -- 用户表
orderlist o -- 订单表
WHERE
u.id=o.uid
-- 2.查询所有的用户。用户的编号、姓名、年龄。订单编号
/*
分析
用户的编号、姓名、年龄 user表 订单编号 orderlist表
条件:user.id=orderlist.uid
查询所有的用户,左外连接
*/
SELECT
u.id, -- 用户编号
u.`NAME`, -- 用户姓名
u.age, -- 用户年龄
o.number -- 订单编号
FROM
`USER` u -- 用户表
LEFT JOIN orderlist o -- 订单表
ON u.id = o.uid
-- 3.查询所有的订单。用户的编号、姓名、年龄。订单编号
/*
分析
用户的编号、姓名、年龄 user表 订单编号 orderlist表
条件:user.id=orderlist.uid
查询所有的订单,右外连接
*/
SELECT
u.id, -- 用户编号
u.`NAME`, -- 用户姓名
u.age, -- 用户年龄
o.number -- 订单编号
FROM
`USER` u -- 用户表
RIGHT JOIN
orderlist o -- 订单表
ON
u.id=o.uid
-- 4.查询用户年龄大于23岁的信息。显示用户的编号、姓名、年龄。订单编号
/*
分析
用户的编号、姓名、年龄 user表 订单编号 orderlist表
条件:user.id=orderlist.uid AND user.age > 23
*/
SELECT
u.id,-- 用户编号
u.`NAME`,-- 用户姓名
u.age,-- 用户年龄
o.number -- 订单编号
FROM
`USER` u,-- 用户表
orderlist o -- 订单表
WHERE
u.id = o.uid
AND u.age > 23
-- 5.查询张三和李四用户的信息。显示用户的编号、姓名、年龄。订单编号
/*
分析
用户的编号、姓名、年龄 user表 订单编号 orderlist表
条件:user.id=orderlist.uid AND user.name IN ('张三','李四')
*/
SELECT
u.id,-- 用户编号
u.`NAME`,-- 用户姓名
u.age,-- 用户年龄
o.number -- 订单编号
FROM
`USER` u, -- 用户表
orderlist o -- 订单表
WHERE
u.id=o.uid
AND
u.`NAME` IN ('张三','李四')
-- 6.查询商品分类的编号、分类名称。分类下的商品名称
/*
分析
商品分类的编号、分类名称 category表 商品名称 product表
条件:category.id=product.cid
*/
SELECT
c.id, -- 商品分类的编号
c.`NAME`, -- 分类名称
p.`NAME`
FROM
category c, -- 商品分类表
product p -- 商品表
WHERE
c.id=p.cid
-- 7.查询所有的商品分类。商品分类的编号、分类名称。分类下的商品名称
/*
分析
商品分类的编号、分类名称 category表 商品名称 product表
条件:category.id=product.cid
查询所有的商品分类,左外连接
*/
SELECT
c.id, -- 分类的编号
c.`NAME`, -- 分类的名称
p.`NAME`-- 商品名称
FROM
category c -- 商品分类表
LEFT JOIN
product p -- 商品表
ON
c.id=p.cid
-- 8.查询所有的商品信息。商品分类的编号、分类名称。分类下的商品名称
/*
分析
商品分类的编号、分类名称 category表 商品名称 product表
条件:category.id=product.cid
查询所有的商品信息,右外连接
*/
SELECT
c.id, -- 分类的编号
c.`NAME`, -- 分类的名称
p.`NAME`-- 商品名称
FROM
category c
RIGHT JOIN
product p
ON
c.id=p.cid
-- 9.查询所有的用户和该用户能查看的所有的商品。显示用户的编号、姓名、年龄。商品名称
/*
分析
用户的编号、姓名、年龄 user表 商品名称 product表 中间表 us_pro
条件:us_pro.uid=user.id AND us_pro.pid=product.id
*/
SELECT
u.*, -- 用户的所有信息
p.`NAME` -- 商品的名称
FROM
`USER` u, -- 用户表
product p, -- 商品表
us_pro up -- 商品和用户的中间表
WHERE
up.uid=u.id
AND
up.pid=p.id
-- 10.查询张三和李四这两个用户可以看到的商品。显示用户的编号、姓名、年龄。商品名称
/*
分析
用户的编号、姓名、年龄 user表 商品名称 product表 中间表 us_pro
条件:us_pro.uid=user.id AND us_pro.pid=product.id AND user.name IN ('张三','李四')
*/
SELECT
u.*,-- 用户的所有信息
p.`NAME` -- 商品的名称
FROM
`USER` u,-- 用户表
product p,-- 商品表
us_pro up -- 中间表
WHERE
up.uid = u.id
AND up.pid = p.id
AND u.`NAME` IN ('张三','李四')