SQL 多表连接

SQL 多表连接

多数SQL查询只包含从一个或多个表中返回数据的单条SELECT语句。但是,SQL也允许执行多个查询(多条SELECT语句),并将结果作为一个查询结果集返回。这些组合查询通常称为并(union)或复合查询(compound query)

主要有两种情况需要使用联结

• 在一个查询中从不同的表返回结构数据;

• 对一个表执行多个查询,按一个查询返回数据。

提示:组合查询和多个WHERE条件多数情况下,组合相同表的两个查询所完成的工作与具有多个WHERE子句条件的一个查询所完成的工作相同。换句话说,任何具有多个WHERE子句的SELECT语句都可以作为一个组合查询. SQL最强大的功能之一就是能在数据查询的执行中联结(join)表。联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的极为重要的部分。”

SELECT 课程号, 课程名 FROM course
UNION 
SELECT 课程号, 课程名 FROM course1. 

表的联结(join): 各表之间建立起联系,并最终联系在一起
交叉联结(cross join) 内联结(inner join) 左联结(left join) 右联结(right join) 全联结(full join)
表和表之间通过列产生关系.涉及到多个表查询用联结。

  1. 交叉联结(cross join):行数是两张表行数的笛卡尔积 类似于矩阵的运算规律

2. 内联结(inner join):查找出同时存在于两张表的数据;学生表和成绩表重合的地方是学号让两张表产生匹配,之后交叉联结;on表示两个表通过on后面的学号产生关系

3. 外联结(outter join)许多联结将一个表中的行与另一个表中的行相关联,但有时候需要包含没有关联行的那些行。与内联结关联两个表中的行不同的是,外联结还包括没有关联行的行。在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)。使用LEFT OUTER JOIN从FROM子句左边的表中选择所有行。为了从右边的表中选择所有行,需要使用RIGHT OUTER JOIN

练习

查询所有学生的学号、姓名、选课数、总成绩

SELECT s.学号, 姓名,  SUM(成绩) AS 总成绩
FROM score AS s LEFT JOIN student AS st
ON( s.学号 = st.学号)
GROUP BY s.学号
ORDER BY SUM(成绩) DESC

查询平均成绩>70的所有学生的学号,姓名,平均成绩

SELECT
	s.学号,
	st.姓名,
	AVG(成绩) AS 平均成绩 
FROM
	score AS s
	LEFT JOIN student AS st ON ( s.学号 = st.学号 ) 
GROUP BY
	s.学号 
HAVING
	AVG(成绩) >= 70
ORDER BY
	AVG(成绩) DESC

查询学生的选课情况:学号,姓名,课程号,课程名称

SELECT
	st.学号,
	st.姓名,
	c.课程号,
	c.课程名 
FROM
	student AS st
	JOIN score AS s ON ( st.学号 = s.学号 )
	JOIN course AS c ON ( s.课程号 = c.课程号 )      


查询每门课程的及格人数和不及格人数

SELECT s.课程号, c.课程名, 
SUM(CASE WHEN s.成绩>=60 THEN 1 ELSE 0 END) AS 及格数, 
SUM(CASE WHEN s.成绩<60 THEN 1 ELSE 0 END) AS 不及格数
FROM score AS s JOIN course AS c ON s.课程号 = c.课程号
GROUP BY s.课程号
UNION
SELECT s.课程号, c1.课程名, 
SUM(CASE WHEN s.成绩>=60 THEN 1 ELSE 0 END) AS 及格数,
SUM(CASE WHEN s.成绩<60 THEN 1 ELSE 0 END) AS 不及格数
FROM score AS s JOIN course1 AS c1 ON s.课程号 = c1.课程号
GROUP BY s.课程号
运行结果

使用分段来统计各科成绩,分别统计各分段人数,课程ID,课程名称

SELECT
	s.课程号,
	c.课程名,
    SUM( CASE WHEN s.成绩 BETWEEN 85 AND 100 THEN 1 ELSE 0 END ) AS '[分段85-100]',
    SUM( CASE WHEN s.成绩 BETWEEN 70 AND 84  THEN 1 ELSE 0 END ) AS '[分段70-84]',
    SUM( CASE WHEN s.成绩 BETWEEN 60 AND 69  THEN 1 ELSE 0 END ) AS '[分段60-69]',
    SUM( CASE WHEN s.成绩 < 60 THEN 1 ELSE 0 END ) AS 不及格
FROM
	score AS s
	JOIN course AS c ON s.课程号 = c.课程号 
GROUP BY
	s.课程号 
    UNION
SELECT
	s.课程号,
	c1.课程名,
    SUM( CASE WHEN s.成绩 BETWEEN 85 AND 100 THEN 1 ELSE 0 END ) AS '[分段85-100]',
    SUM( CASE WHEN s.成绩 BETWEEN 70 AND 84  THEN 1 ELSE 0 END ) AS '[分段70-84]',
    SUM( CASE WHEN s.成绩 BETWEEN 60 AND 69  THEN 1 ELSE 0 END ) AS '[分段60-69]',
    SUM( CASE WHEN s.成绩 < 60 THEN 1 ELSE 0 END ) AS 不及格
FROM
	score AS s
	JOIN course1 AS c1 ON s.课程号 = c1.课程号 
GROUP BY
	s.课程号

SQLZOO

发布于 2020-01-19 21:55