4. 下午题 SQL 实战知识体系
“软考下午题的 SQL 查询通常由这五种核心逻辑组合而成,掌握套路比死记硬背更重要。”
套路一:聚合统计与分组过滤 (Group By)
逻辑: 只要使用了 SUM/AVG 等聚合函数,非计算字段必须进入 GROUP BY;对汇总后的结果筛选必须用 HAVING。
-- 查询购买过“家电”的客户名及总购买量,并降序排列
SELECT c.CustName, SUM(o.Qty) AS Total
FROM Orders o
JOIN Customers c ON o.CustID = c.CustID
JOIN Products p ON o.ProductID = p.ProductID
WHERE p.Category = '家电' -- 聚合前的初筛
GROUP BY c.CustName
ORDER BY Total DESC;
套路二:否定型查询 (排除法逻辑)
逻辑: 面对“从来没有”、“不曾购买”这类条件,先用子查询抓出“做过的人”组成黑名单,再用 NOT IN 剔除。
-- 查询从来没有购买过单价超过 5000 元产品的客户
SELECT CustID, CustName FROM Customers
WHERE CustID NOT IN (
SELECT o.CustID FROM Orders o
JOIN Products p ON p.ProductID = o.ProductID
WHERE p.Price > 5000
);
套路三:查漏补缺 (LEFT JOIN 匹配法)
逻辑: 利用左连接保留左表全量的特性。右表(订单表)匹配不上的客户,其关联字段必定是 NULL。
-- 查询已注册但没有任何订单记录的客户名
SELECT c.CustName FROM Customers c
LEFT JOIN Orders o ON c.CustID = o.CustID
WHERE o.OrderID IS NULL;
套路四:标量子查询对比 (组对比全局)
逻辑: 当需要将各组的数据(如班级平均分)与全局数据(如全校总平均分)对比时,在 HAVING 后面嵌套一个只返回单值的子查询。
-- 查询平均分超过“全校总平均分”的班级号
SELECT 班级号 FROM Scores
GROUP BY 班级号
HAVING AVG(分数) > (SELECT AVG(分数) FROM Scores);
套路五:自连接查询 (自己跟自己比)
逻辑: 同一张表起两个别名(如 e 代表员工,m 代表经理),通过连接条件建立逻辑关联。
-- 查询工资比其直接经理还要高的员工名
SELECT e.EmpName FROM Employee e, Employee m
WHERE e.ManagerID = m.EmpID AND e.Salary > m.Salary;
🚨 考场避坑准则:
1. NULL 判定:严禁写 = NULL,必须写 IS NULL。
2. 执行顺序:FROM ➔ WHERE ➔ GROUP BY ➔ HAVING ➔ SELECT ➔ ORDER BY。
3. 别名使用:在 WHERE 里不能直接引用 SELECT 定义的别名(因为顺序太靠前)。