今天介紹下關于高級查詢的詳細介紹,包括子查詢、連接查詢、分組查詢等,并結合MySQL數據庫提供實際例子。
一、子查詢(Subqueries)
子查詢是嵌套在另一個查詢中的查詢語句,通常用于提供條件過濾、生成臨時數據集等。子查詢可以出現在SELECT
、FROM
、WHERE
、HAVING
等子句中。
1. 標量子查詢(Scalar Subquery)
標量子查詢返回單個值,通常用于比較操作。
示例1:查詢工資高于平均工資的員工
SELECT employee_id, name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
解釋:外層查詢從employees
表中獲取員工信息,內層子查詢計算所有員工的平均工資,外層查詢的WHERE
子句將篩選出工資高于平均工資的員工。
示例2:查詢與員工Alice同部門的其他員工
SELECT employee_id, name
FROM employees
WHERE department_id = (SELECT department_id FROM employees WHERE name = 'Alice');
解釋:內層子查詢找到Alice所在的部門ID,外層查詢根據這個部門ID篩選出其他同部門的員工。
2. 行子查詢(Row Subquery)
行子查詢返回一行數據,通常用于比較操作符(如IN
、ANY
、ALL
)。
示例1:查詢工資高于部門平均工資的員工
SELECT e.employee_id, e.name, e.salary
FROM employees e
WHERE (e.department_id, e.salary) > ANY (SELECT department_id, AVG(salary)FROM employeesGROUP BY department_id
);
解釋:內層子查詢按部門分組計算每個部門的平均工資,外層查詢使用ANY
比較操作符,篩選出工資高于所在部門平均工資的員工。
示例2:查詢與Alice和Bob同部門的員工
SELECT employee_id, name
FROM employees
WHERE (department_id, name) IN (SELECT department_id, nameFROM employeesWHERE name IN ('Alice', 'Bob')
);
解釋:內層子查詢找到Alice和Bob的部門ID和姓名,外層查詢使用IN
操作符篩選出與他們同部門的員工。
3. 表子查詢(Table Subquery)
表子查詢返回一個表,通常用于FROM
子句中。
示例1:查詢每個部門工資最高的員工
SELECT e.employee_id, e.name, e.salary, e.department_id
FROM employees e
JOIN (SELECT department_id, MAX(salary) AS max_salaryFROM employeesGROUP BY department_id
) AS max_sal
ON e.department_id = max_sal.department_id AND e.salary = max_sal.max_salary;
解釋:內層子查詢按部門分組,計算每個部門的最高工資。外層查詢通過JOIN
將employees
表與子查詢結果連接,篩選出每個部門工資最高的員工。
示例2:查詢每個部門的員工數量和平均工資
SELECT d.department_id, d.department_name, COUNT(e.employee_id) AS employee_count, AVG(e.salary) AS avg_salary
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_id, d.department_name;
解釋:雖然這里沒有顯式的表子查詢,但LEFT JOIN
的結果可以視為一個表子查詢。查詢統計了每個部門的員工數量和平均工資。
二、連接查詢(Joins)
連接查詢用于將兩個或多個表中的數據組合在一起。MySQL支持多種連接類型,包括INNER JOIN
、LEFT JOIN
、RIGHT JOIN
、FULL JOIN
(MySQL不支持FULL JOIN
,但可以通過UNION
實現)。
1. 內連接(INNER JOIN)
內連接返回兩個表中匹配的行。
示例1:查詢員工及其所在部門的信息
SELECT e.employee_id, e.name, d.department_name
FROM employees e
INNER JOIN departments d
ON e.department_id = d.department_id;
解釋:INNER JOIN
將employees
表和departments
表連接,返回員工及其所在部門的信息。
示例2:查詢員工及其經理的信息
SELECT e.employee_id, e.name AS employee_name, m.name AS manager_name
FROM employees e
INNER JOIN employees m
ON e.manager_id = m.employee_id;
解釋:employees
表自連接,e
表示員工,m
表示經理,查詢返回每個員工及其經理的名稱。
2. 外連接(Outer Join)
外連接返回一個表中的所有行,即使另一個表中沒有匹配的行。
示例1:查詢所有員工及其所在部門的信息,即使某些員工沒有分配部門
SELECT e.employee_id, e.name, d.department_name
FROM employees e
LEFT JOIN departments d
ON e.department_id = d.department_id;
解釋:LEFT JOIN
確保返回employees
表中的所有行,即使departments
表中沒有匹配的行(部門名稱為NULL
)。
示例2:查詢所有部門及其員工的信息,即使某些部門沒有員工
SELECT d.department_id, d.department_name, e.name AS employee_name
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id;
解釋:LEFT JOIN
確保返回departments
表中的所有行,即使employees
表中沒有匹配的行(員工名稱為NULL
)。
3. 自連接(Self Join)
自連接是將一個表與自身連接,通常用于比較表中的不同行。
示例1:查詢員工及其直接上級的信息
SELECT e.employee_id, e.name AS employee_name, m.name AS manager_name
FROM employees e
JOIN employees m
ON e.manager_id = m.employee_id;
解釋:employees
表自連接,e
表示員工,m
表示經理,查詢返回每個員工及其直接上級的名稱。
示例2:查詢員工及其所有上級的信息(多級)
WITH RECURSIVE EmployeeHierarchy AS (SELECT employee_id, name, manager_id, 1 AS levelFROM employeesWHERE manager_id IS NULL -- 假設經理ID為NULL表示最高級UNION ALLSELECT e.employee_id, e.name, e.manager_id, eh.level + 1FROM employees eJOIN EmployeeHierarchy ehON e.manager_id = eh.employee_id
)
SELECT employee_id, name, manager_id, level
FROM EmployeeHierarchy;
解釋:使用遞歸公用表表達式(CTE)實現多級自連接,查詢每個員工及其所有上級的信息。
三、分組查詢(GROUP BY)
分組查詢用于將數據按指定列分組,并對每個分組進行聚合計算。GROUP BY
子句通常與聚合函數(如SUM
、AVG
、COUNT
等)一起使用。
1. 基本分組
按指定列分組并計算聚合值。
示例1:查詢每個部門的員工數量
SELECT department_id, COUNT(employee_id) AS employee_count
FROM employees
GROUP BY department_id;
解釋:按department_id
分組,計算每個部門的員工數量。
示例2:查詢每個部門的平均工資
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
解釋:按department_id
分組,計算每個部門的平均工資。
2. 分組過濾(HAVING)
HAVING
子句用于過濾分組后的結果,與WHERE
子句不同,HAVING
子句可以使用聚合函數。
示例1:查詢員工數量大于5的部門
SELECT department_id, COUNT(employee_id) AS employee_count
FROM employees
GROUP BY department_id
HAVING COUNT(employee_id) > 5;
解釋:按department_id
分組,使用HAVING
子句過濾出員工數量大于5的部門。
示例2:查詢平均工資大于5000的部門
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 5000;
解釋:按department_id
分組,使用HAVING
子句過濾出平均工資大于5000的部門。
3. 分組排序(ORDER BY)
ORDER BY
子句用于對分組后的結果進行排序。
示例1:查詢每個部門的員工數量,并按員工數量降序排序
SELECT department_id, COUNT(employee_id) AS employee_count
FROM employees
GROUP BY department_id
ORDER BY employee_count DESC;
解釋:按department_id
分組,計算每個部門的員工數量,并按員工數量降序
以上就是基于Mysql,有關查詢相關的進階知識,希望對你有所幫助~
后續會連續發布多篇SQL進階相關內容;
期待你的關注,學習更多知識;