联结查询
联结通常效率比子查询高
——<SQL必知必会>
联结查询可以将多个表的数据结合在一起进行查询
内联结
SELECT column1
FROM Table1 INNER JOIN Table2
ON 条件;
若不设置条件,内联结默认为笛卡尔积
自联结
自身连接, 此时可以为表设置别名
SELECT column1
-- 将两个Table分别设置别名T1, T2
FROM Table1 AS T1, Table1 AS T2
...
自然联结
自然联结可以避免出现重复的列
在SELECT
中指定表.列
外联结
可以包含没有关联的行
SELECT column1
FROM Table1 LEFT OUTER JOIN Table2
ON 条件;
外联结分左外联结,右外联结,全外联结
(LEFT OUTER JOIN
RIGHT OUTER JOIN
FULL OUTER JOIN
)
例如左外联结,意味着左表要保留所有行,即使没有对应的右表关联行
如果是想查询右表中为NULL的部分, 需用 IS NULL
, 不能用=
结果集操作(组合查询)
就是对查询的结果集使用集合代数中的交, 并, 差
需要结果集的列之间必须相同
并集-UNION
两条查询语句可以用UNION
组合, 即两个结果集的并集
SELECT ...
...
UNION
SELECT ...
...
得到的查询结果会自动去重. 如果的确需要重复结果,使用UNION ALL
即可.
组合的查询可以有多个,但 ORDER BY
只能有一个放在结尾
差集-EXCEPT
类似上面的并集, 交集在两条查询语句间加入EXCEPT
交集-INTERSECT
类似上面的并集, 交集在两条查询语句间加入INTERSECT
子查询
子查询由嵌套的多个SQL语句组成, 例如将子查询作为条件:
SELECT column1, column2
FROM Table1
WHERE column1 = (
SELECT column1
FROM Table2
WHERE 条件
);
不相关子查询
即子查询与父查询各查各的, 互不干扰
相关子查询
子查询要用到父查询的结果是相关子查询
此时父查询查出一条, 子查询比对一条
再例如使用书上数据库查询每个系的总分第一名
-- 查询每个系的总分第一名, 列出姓名, 系别, 总分
-- 使用相关子查询
-- 首先父查询获取一条Student, SC两表的等值连接的记录
-- 子查询找出与父查询本条查询结果 系别一致的系 的最高分 的学号
-- 父查询再比对是否是本条记录
SELECT Sname, Sdept, SUM(Grade) AS Gsum
FROM Student SOut JOIN SC ON SOut.Sno = SC.Sno
WHERE SOut.Sno = (
SELECT TOP 1 S.Sno
FROM SC
JOIN Student S ON SC.Sno = S.Sno
WHERE S.Sdept = SOut.Sdept
GROUP BY S.Sno, S.Sdept
ORDER BY SUM(Grade) DESC
)
GROUP BY Sname, Sdept;