在 SQL 查询里,如果在 SELECT、WHERE 和 ORDER BY 中反复书写同一个复杂表达式,数据库很可能多次执行相同计算,造成资源浪费。通过重构查询结构,可以有效避免这种重复计算。

为什么会出现重复计算
看下面这个例子,我们对销售额做折扣计算并在多个地方使用:
SELECT product_id, price * (1 - discount) AS final_price, price * (1 - discount) * quantity AS total FROM orders WHERE price * (1 - discount) > 100 ORDER BY price * (1 - discount) DESC;
这里 price * (1 - discount) 出现了三次。某些数据库优化器会合并,但复杂场景下仍可能重复执行。
使用派生表避免重复
把计算放到子查询里,外层直接引用别名:
SELECT
product_id,
final_price,
final_price * quantity AS total
FROM (
SELECT
product_id,
price * (1 - discount) AS final_price,
quantity,
price
FROM orders
) t
WHERE final_price > 100
ORDER BY final_price DESC;
使用 CTE 公共表表达式
CTE 写法更清晰,适合多次引用:
WITH calc AS (
SELECT
product_id,
price * (1 - discount) AS final_price,
quantity
FROM orders
)
SELECT
product_id,
final_price,
final_price * quantity AS total
FROM calc
WHERE final_price > 100
ORDER BY final_price DESC;
利用窗口函数减少聚合重复
当既要明细又要汇总时,不用子查询重复聚合:
SELECT product_id, amount, SUM(amount) OVER (PARTITION BY category_id) AS cat_total FROM sales;
小结
避免在 SQL SELECT 中重复计算的核心是:先算一次,后用别名。派生表、CTE 和窗口函数都是实用手段。建议在写完查询后查看执行计划,确认计算是否被有效复用。