子查詢可以返回各種不同類型的信息
- 標量子查詢返回一個值霹肝;(最嚴格的,適用范圍也最大)
- 列子查詢返回一個由一個值或多個值構成的列;
- 行子查詢返回一個由一個值或多個值構成的行恭金;
- 表子查詢返回一個由一個行或多個行構成的表坟瓢,而行則由一個或多個列構成勇边。
帶關系比較運算符的子查詢
運算符:=、<>折联、>粥诫、>=、< 和 <= 崭庸。
-- 一般的子查詢,有時候為了滿足返回一個值的要求怀浆,可以使用 LIMIT 1 來限制
SELECT * FROM president
WHERE brith = (SELECT min(brith) FROM president);
-- 使用一個行構造器來實現一組值(即元組)與子查詢結果的比較
-- ROW(city,state) 等價于 (city,state)
SELECT last_name,first_name,city,state FROM president
WHERE (city,state) = (
SELECT city,state FROM president WHERE last_name='Adam' AND first_name='John'
);
IN 和 NOT IN 子查詢
-- 查詢有缺勤記錄的學生
SELECT * FROM student WHERE student_id
IN (SELECT student_id FROM absence);
-- 查詢沒有缺勤記錄的學生
SELECT * FROM student WHERE student_id
NOT IN (SELECT student_id FROM absence);
-- 也可以使用行構造器來指定與各列進行比較
SELECT last_name,first_name,city,state FROM president
WHERE (city,state) IN (
SELECT city,state FROM president
WHERE last_name = 'Roosevelt'
);
ALL、ANY 和 SOME 子查詢
IN 和 NOT IN 是 = ANY 和 <> ALL 的縮寫
-- 檢索最早出生的總統(tǒng)
SELECT last_name,first_name,brith FROM president
WHERE brith <= ALL (SELECT brith FROM president);
-- 行構造器
SELECT last_name,first_name,city,state FROM president
WHERE (city,state) = ANY (
SELECT city,state FROM president WHERE last_name = 'Roosevelt'
);
EXISTS 和 NOT EXISTS 子查詢
-- 根據子查詢是否返回了行來判斷真假怕享,并不關心行所包含的具體內容执赡,所以使用 select 1
SELECT exists(SELECT 1 FROM absence);
SELECT NOT exists(SELECT 1 FROM absence);
相關子查詢
-- 不相關的子查詢不會引用外層查詢里的值,因此它自己可以作為一條的單獨查詢命令去執(zhí)行
SELECT j FROM t2 WHERE j IN (SELECT i FROM t1);
-- 相關子查詢則引用了外層查詢里的值函筋,所以它也就依賴于外層查詢沙合。
-- 通常用在 EXISTS 和 NOT EXISTS 子查詢里
SELECT j FROM t2 WHERE (SELECT i FROM t1 WHERE i = j);
FROM 子句里的子查詢
-- 子查詢可以用在 FROM 子句里,以生成某些值跌帐。
SELECT * FROM (SELECT 1,2) AS t1 INNER JOIN (SELECT 3,4) AS t2;
將子查詢改寫為連接
-- 改寫用來查詢匹配值的子查詢
SELECT * FROM score
WHERE student_id IN (SELECT student_id FROM student WHERE sex='F');
-- 改寫成
SELECT score.* FROM score INNER JOIN student
ON score.student_id = student.student_id WHERE student.sex = 'F';
-- 改寫用來查詢非匹配(缺失)值的子查詢
SELECT * FROM student
WHERE student_id NOT IN (SELECT student_id FROM absence);
-- 改寫成
SELECT student.*
FROM student LEFT JOIN absence ON student.student_id = absence.student_id
WHERE absence.student_id IS NULL ;
使用 UNION 實現多表檢索
-- UNION 有以下幾種特性:
-- ①首懈、列名和數據類型:UNION 結果集里的列名來自于第一個 SELECT 里的列名
SELECT i1,c1 FROM t1 UNION SELECT i2,c2 FROM t2;
SELECT i1,c1 FROM t1 UNION SELECT c2,i2 FROM t2;
-- ②绊率、重復行處理:默認情況下,UNION 會將結果集里的重復行剔除掉
SELECT * FROM t1 UNION SELECT * FROM t2;
-- 如果想保留重復的行究履,則需要把所有的 UNION 改為 UNION ALL
SELECT * FROM t1 UNION ALL SELECT * FROM t2;
-- ③滤否、ORDER BY 和 LIMIT 處理
-- 注意:order by 只能引用第一個 select 語句里的列名
(SELECT i1,c1 FROM t1 LIMIT 1) UNION (SELECT i2,c2 FROM t2 LIMIT 2)
ORDER BY c1
LIMIT 2;