多表查询:
学生表、班级表、课程表、班级课程表


-- 多对多
-- 班级表
CREATE
TABLE
banji(
id
INT
PRIMARY
KEY
AUTO_INCREMENT,
`
name
`
VARCHAR
(10)
NOT
NULL
);
INSERT
INTO
banji(`
name
`)
VALUES
(
'java1807'
),(
'java1812'
);
SELECT
*
FROM
banji;
-- 学生表
CREATE
TABLE
student(
id
INT
PRIMARY
KEY
AUTO_INCREMENT,
`
name
`
VARCHAR
(10)
NOT
NULL
,
age
INT
,
gender
CHAR
(1),
banji_id
INT
,
FOREIGN
KEY
(banji_id)
REFERENCES
banji(id)
);
INSERT
INTO
student(`
name
`,age,gender,banji_id)
VALUES
(
'张三'
,20,
'男'
,1),(
'李四'
,21,
'男'
,2),(
'王五'
,20,
'女'
,1);
-- Cannot add or update a child row: a foreign key constraint fails (`java1812`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`banji_id`) REFERENCES `banji` (`id`))
INSERT
INTO
student(`
name
`,age,gender,banji_id)
VALUES
(
'张三'
,20,
'男'
,3);
SELECT
*
FROM
student;
-- 课程表
CREATE
TABLE
course(
id
INT
PRIMARY
KEY
AUTO_INCREMENT,
`
name
`
VARCHAR
(10)
NOT
NULL
,
credit
INT
COMMENT
'学分'
);
INSERT
INTO
course(`
name
`,credit)
VALUES
(
'Java'
,5),(
'UI'
,4),(
'H5'
,4);
SELECT
*
FROM
course;
-- 班级课程表
CREATE
TABLE
banji_course(
-- id int PRIMARY KEY AUTO_INCREMENT,
banji_id
INT
,
course_id
INT
,
PRIMARY
KEY
(banji_id,course_id),
-- 联合主键
FOREIGN
KEY
(banji_id)
REFERENCES
banji(id),
-- banji_id既是联合主键又是外键
FOREIGN
KEY
(course_id)
REFERENCES
course(id)
-- course_id既是联合主键又是外键
);
INSERT
INTO
banji_course(banji_id,course_id)
VALUES
(1,1),(1,3),(2,1),(2,2),(2,3);
SELECT
*
FROM
banji_course;
-- 子查询:嵌套查询,一个查询语句是另一个查询语句的条件
-- 查询班级是java1812班所有学生信息
SELECT
*
FROM
student
WHERE
banji_id=2;
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1812'
;
SELECT
*
FROM
student
WHERE
banji_id=(
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1812'
);
-- 班级是java1807班或者java1812班所有学生信息
SELECT
*
FROM
student
WHERE
banji_id=1
OR
banji_id=2;
SELECT
*
FROM
student
WHERE
banji_id
IN
(1,2);
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1807'
OR
`
name
`=
'java1812'
;
-- 1,2
SELECT
*
FROM
student
WHERE
banji_id
IN
(
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1807'
OR
`
name
`=
'java1812'
);
-- "=":要求子查询只有一个结果。 "in":子查询可以有多个结果
关联查询:inner join
多表查询:
学生表、班级表、课程表、班级课程表


-- 多对多
-- 班级表
CREATE
TABLE
banji(
id
INT
PRIMARY
KEY
AUTO_INCREMENT,
`
name
`
VARCHAR
(10)
NOT
NULL
);
INSERT
INTO
banji(`
name
`)
VALUES
(
'java1807'
),(
'java1812'
);
SELECT
*
FROM
banji;
-- 学生表
CREATE
TABLE
student(
id
INT
PRIMARY
KEY
AUTO_INCREMENT,
`
name
`
VARCHAR
(10)
NOT
NULL
,
age
INT
,
gender
CHAR
(1),
banji_id
INT
,
FOREIGN
KEY
(banji_id)
REFERENCES
banji(id)
);
INSERT
INTO
student(`
name
`,age,gender,banji_id)
VALUES
(
'张三'
,20,
'男'
,1),(
'李四'
,21,
'男'
,2),(
'王五'
,20,
'女'
,1);
-- Cannot add or update a child row: a foreign key constraint fails (`java1812`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`banji_id`) REFERENCES `banji` (`id`))
INSERT
INTO
student(`
name
`,age,gender,banji_id)
VALUES
(
'张三'
,20,
'男'
,3);
SELECT
*
FROM
student;
-- 课程表
CREATE
TABLE
course(
id
INT
PRIMARY
KEY
AUTO_INCREMENT,
`
name
`
VARCHAR
(10)
NOT
NULL
,
credit
INT
COMMENT
'学分'
);
INSERT
INTO
course(`
name
`,credit)
VALUES
(
'Java'
,5),(
'UI'
,4),(
'H5'
,4);
SELECT
*
FROM
course;
-- 班级课程表
CREATE
TABLE
banji_course(
-- id int PRIMARY KEY AUTO_INCREMENT,
banji_id
INT
,
course_id
INT
,
PRIMARY
KEY
(banji_id,course_id),
-- 联合主键
FOREIGN
KEY
(banji_id)
REFERENCES
banji(id),
-- banji_id既是联合主键又是外键
FOREIGN
KEY
(course_id)
REFERENCES
course(id)
-- course_id既是联合主键又是外键
);
INSERT
INTO
banji_course(banji_id,course_id)
VALUES
(1,1),(1,3),(2,1),(2,2),(2,3);
SELECT
*
FROM
banji_course;
-- 子查询:嵌套查询,一个查询语句是另一个查询语句的条件
-- 查询班级是java1812班所有学生信息
SELECT
*
FROM
student
WHERE
banji_id=2;
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1812'
;
SELECT
*
FROM
student
WHERE
banji_id=(
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1812'
);
-- 班级是java1807班或者java1812班所有学生信息
SELECT
*
FROM
student
WHERE
banji_id=1
OR
banji_id=2;
SELECT
*
FROM
student
WHERE
banji_id
IN
(1,2);
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1807'
OR
`
name
`=
'java1812'
;
-- 1,2
SELECT
*
FROM
student
WHERE
banji_id
IN
(
SELECT
id
FROM
banji
WHERE
`
name
`=
'java1807'
OR
`
name
`=
'java1812'
);
-- "=":要求子查询只有一个结果。 "in":子查询可以有多个结果
关联查询:inner join


-- 列出所有学生学习的课程名称
-- 学生姓名 班级名称 课程名称 学分



-- inner join on 只有左右两个表有关联的才查询出来
-- left join on 左表中都显示出来,右表没有显示空
-- right join on 右表都显示,左表没有显示空

SELECT
*
FROM
student
as
s
INNER
JOIN
banji
as
b
on
s.banji_id=b.id;
SELECT
*
FROM
student
as
s
LEFT
JOIN
banji
as
b
on
s.banji_id=b.id;

SELECT
*
FROM student
as s
RIGHT
JOIN banji
as b
on
s.banji_id=b.id;

-- 没有分配课程也显示出来。
-- 班级名称 课程名称 学分
SELECT b.`
name`
AS
'班级名称',c.`
name`
as
'课程名称',c.credit
as
'学分'
FROM banji
AS b
LEFT
JOIN banji_course
AS bc
ON b.id=bc.banji_id
LEFT
JOIN course
as c
ON
bc.course_id=c.id;

总结:多表查询主要是注意下面两点
1、整个查询涉及到几张表,涉及到几张表就连接这几张表。
2、如果涉及到这几张表的关系搞不清楚,画一下ER图,弄清楚表和表之间的关系(就是根据外键建立的关系)
-- 统计每个班有多少学生
-- 学生数量
SELECT
COUNT
(id)
as
'学生数量'
FROM
student
GROUP
BY
banji_id;
-- 班级名称 数量
SELECT
*
FROM
student
as
s
INNER
JOIN
banji
as
b
ON
s.banji_id=b.id;

把inner join之后查询的结果当成一张表来使用, 在这个结果集里面根据班级id统计每个班级下面学生数量。

-- 列出所有学生学习的课程名称
-- 学生姓名 班级名称 课程名称 学分



-- inner join on 只有左右两个表有关联的才查询出来
-- left join on 左表中都显示出来,右表没有显示空
-- right join on 右表都显示,左表没有显示空

SELECT
*
FROM
student
as
s
INNER
JOIN
banji
as
b
on
s.banji_id=b.id;
SELECT
*
FROM
student
as
s
LEFT
JOIN
banji
as
b
on
s.banji_id=b.id;

SELECT
*
FROM student
as s
RIGHT
JOIN banji
as b
on
s.banji_id=b.id;

-- 没有分配课程也显示出来。
-- 班级名称 课程名称 学分
SELECT b.`
name`
AS
'班级名称',c.`
name`
as
'课程名称',c.credit
as
'学分'
FROM banji
AS b
LEFT
JOIN banji_course
AS bc
ON b.id=bc.banji_id
LEFT
JOIN course
as c
ON
bc.course_id=c.id;

总结:多表查询主要是注意下面两点
1、整个查询涉及到几张表,涉及到几张表就连接这几张表。
2、如果涉及到这几张表的关系搞不清楚,画一下ER图,弄清楚表和表之间的关系(就是根据外键建立的关系)
-- 统计每个班有多少学生
-- 学生数量
SELECT
COUNT
(id)
as
'学生数量'
FROM
student
GROUP
BY
banji_id;
-- 班级名称 数量
SELECT
*
FROM
student
as
s
INNER
JOIN
banji
as
b
ON
s.banji_id=b.id;

把inner join之后查询的结果当成一张表来使用, 在这个结果集里面根据班级id统计每个班级下面学生数量。