SQL 面試攻略:從普通到困難的副本通關(guān)之旅
本文匯總了一些 SQL 面試中經(jīng)典且具有代表性的題目,涵蓋普通和困難模式,幫助讀者熟悉一些常考的 SQL 問題。每道題均附有詳細(xì)解答,提供示例代碼和解析。
示例表結(jié)構(gòu)
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
salary DECIMAL(10, 2),
manager_id INT,
department_id INT
);
CREATE TABLE departments (
id INT PRIMARY KEY,
name VARCHAR(50)
);
普通模式
1. 計(jì)算每個(gè)部門的平均工資,并只顯示平均工資超過 6000 的部門
解答:
SELECT department_id, AVG(salary) as avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 6000;
解析:這個(gè)查詢使用了 GROUP BY 子句進(jìn)行分組,AVG () 函數(shù)計(jì)算平均值,HAVING 子句用于過濾分組后的結(jié)果。
2. 查詢 employees 表中每個(gè)部門工資最高的員工姓名和工資
解答:
SELECT e.name, e.salary, e.department_id
FROM employees e
WHERE e.salary = (
SELECT MAX(salary)
FROM employees
WHERE department_id = e.department_id
);
解析:
- 通過子查詢找出每個(gè)部門的最高工資。
- 使用外層查詢關(guān)聯(lián)部門和最高工資對(duì)應(yīng)的員工。
3. 找出工資高于公司平均工資的所有員工
解答:
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
解析:這個(gè)查詢使用了子查詢來計(jì)算平均工資,然后在主查詢中使用這個(gè)結(jié)果進(jìn)行比較。
4. 查詢兩個(gè)表 employees 和 departments,展示每位員工的姓名和所屬部門的名稱
解答:
SELECT e.name AS employee_name, d.name AS department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;
解析:
- 使用 INNER JOIN 連接兩張表。
- 考查多表關(guān)聯(lián)查詢。
- 困難模式
5. 查詢 employees 表中所有重復(fù)的姓名及其出現(xiàn)次數(shù)
解答:
SELECT name, COUNT(*) AS name_count
FROM employees
GROUP BY name
HAVING COUNT(*) > 1;
解析:
- 使用 GROUP BY 對(duì)名字分組。
- HAVING 子句篩選分組后的數(shù)據(jù)。
- 考查聚合和過濾的結(jié)合使用。
6. 查詢連續(xù)三個(gè)月工資增長的員工姓名
示例表結(jié)構(gòu):
CREATE TABLE salaries (
employee_id INT,
month DATE,
salary DECIMAL(10, 2),
PRIMARY KEY (employee_id, month)
);
解答:
SELECT DISTINCT s1.employee_id
FROM salaries s1
JOIN salaries s2 ON s1.employee_id = s2.employee_id AND DATE_ADD(s1.month, INTERVAL 1 MONTH) = s2.month
JOIN salaries s3 ON s2.employee_id = s3.employee_id AND DATE_ADD(s2.month, INTERVAL 1 MONTH) = s3.month
WHERE s1.salary < s2.salary AND s2.salary < s3.salary;
解析:
- 通過自連接比較同一員工在連續(xù)月份的工資。
- 使用 DATE_ADD 處理日期計(jì)算。
- 考查自連接和復(fù)雜條件查詢。
7. 查詢員工的累計(jì)工資排名(按工資降序排列)
解答:
SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees;
解析:
- 使用窗口函數(shù) RANK() 實(shí)現(xiàn)排名。
- 考查窗口函數(shù)的使用。
8. 對(duì)于每個(gè)部門,查找工資排名前三的員工
解答:
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) as rank
FROM employees
) ranked
WHERE rank <= 3;
解析:這個(gè)查詢使用了窗口函數(shù) DENSE_RANK () 來為每個(gè)部門的員工根據(jù)工資進(jìn)行排名,然后在外部查詢中篩選出排名前三的記錄。
9. 顯示所有員工及其所有上級(jí)管理者的姓名
解答:
WITH RECURSIVE emp_hierarchy AS (
SELECT id, name, manager_id
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id
FROM employees e
JOIN emp_hierarchy eh ON e.manager_id = eh.id
)
SELECT e.name as employee, GROUP_CONCAT(m.name ORDER BY m.id) as managers
FROM emp_hierarchy e
LEFT JOIN emp_hierarchy m ON e.id != m.id AND e.id = m.manager_id
GROUP BY e.id, e.name;
解析:這是一個(gè)遞歸公共表表達(dá)式(CTE)查詢,用于處理層級(jí)數(shù)據(jù)。它首先找到頂級(jí)管理者,然后遞歸地找到所有下屬。
結(jié)語
SQL 面試題往往注重以下能力:
- 數(shù)據(jù)查詢、過濾與分組:如 SELECT、WHERE、GROUP BY。
- 多表操作:如 JOIN、子查詢。
- 高級(jí)特性:如窗口函數(shù)、自連接。