在SQL中,多表查詢用于從多個表中組合數據,常見的方法包括 ?連接查詢(JOIN)?? 和 ?子查詢。以下是詳細說明和示例:
一、連接查詢(JOIN)
通過關聯字段將多個表的數據合并,分為以下幾種類型:
1. 內連接(INNER JOIN)
- ?作用?:只返回兩表中匹配的行。
- ?語法?:
SELECT 列名 FROM 表1 INNER JOIN 表2 ON 表1.關聯字段 = 表2.關聯字段;
- ?示例?:
-- 查詢員工及其所屬部門信息(僅匹配的記錄) SELECT e.name, d.department_name FROM employees e INNER JOIN departments d ON e.dept_id = d.id;
2. 左外連接(LEFT JOIN / LEFT OUTER JOIN)
- ?作用?:返回左表所有行,右表無匹配則填充
NULL
。 - ?語法?:
SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.關聯字段 = 表2.關聯字段;
- ?示例?:
-- 查詢所有員工及部門信息(包括無部門的員工) SELECT e.name, d.department_name FROM employees e LEFT JOIN departments d ON e.dept_id = d.id;
3. 右外連接(RIGHT JOIN / RIGHT OUTER JOIN)
- ?作用?:返回右表所有行,左表無匹配則填充
NULL
。 - ?語法?:
SELECT 列名 FROM 表1 RIGHT JOIN 表2 ON 表1.關聯字段 = 表2.關聯字段;
- ?示例?:
-- 查詢所有部門及員工信息(包括無員工的部門) SELECT e.name, d.department_name FROM employees e RIGHT JOIN departments d ON e.dept_id = d.id;
4. 全外連接(FULL JOIN / FULL OUTER JOIN)
- ?作用?:返回兩表所有行,無匹配則填充
NULL
(部分數據庫如MySQL不直接支持,需用UNION
模擬)。 - ?語法?(以MySQL為例):
SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.關聯字段 = 表2.關聯字段 UNION SELECT 列名 FROM 表1 RIGHT JOIN 表2 ON 表1.關聯字段 = 表2.關聯字段;
5. 交叉連接(CROSS JOIN)
- ?作用?:返回兩表的笛卡爾積(所有可能的組合)。
- ?語法?:
SELECT 列名 FROM 表1 CROSS JOIN 表2;
- ?注意?:結果行數 = 表1行數 × 表2行數,需謹慎使用。
二、子查詢
在查詢中嵌套另一個查詢,分為以下場景:
1. WHERE子句中的子查詢
- ?示例?:查詢工資高于平均工資的員工。
SELECT name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
2. FROM子句中的子查詢(派生表)
- ?示例?:將子查詢結果作為臨時表使用。
SELECT dept_avg.dept_id, dept_avg.avg_salary FROM (SELECT dept_id, AVG(salary) AS avg_salary FROM employees GROUP BY dept_id) AS dept_avg WHERE dept_avg.avg_salary > 5000;
3. SELECT子句中的子查詢(標量子查詢)
- ?示例?:查詢員工姓名及其部門名稱(通過子查詢獲取部門名)。
SELECT e.name,(SELECT d.department_name FROM departments d WHERE d.id = e.dept_id) AS department_name FROM employees e;
三、多表連接的注意事項
- ?明確關聯字段?:確保連接條件正確,避免笛卡爾積。
- ?性能優化?:
- 為關聯字段建立索引。
- 避免過多的表連接(一般不超過3-4張表)。
- ?結果去重?:使用
DISTINCT
消除重復行(如多表連接導致重復)。
四、實際案例
?場景?:查詢“銷售部門”的所有員工姓名及其職位。
-- 方法1:內連接
SELECT e.name, e.position
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id
WHERE d.department_name = '銷售部';-- 方法2:子查詢
SELECT name, position
FROM employees
WHERE dept_id = (SELECT id FROM departments WHERE department_name = '銷售部');
通過靈活組合連接和子查詢,可以高效處理復雜的數據關聯需求。根據場景選擇合適的方法,并注意性能優化!
?