如何在选择中一遍又一遍地避免对列值进行相同的计算?

时间:2010-04-07 01:18:22

标签: sql sql-server-2005

我有时在表单上写SELECT:

SELECT
    a.col1 + b.col2 * c.col4 as calc_col1,
    a.col1 + b.col2 * c.col4 + xxx as calc_col1_PLUS_MORE
FROM ....
INNER JOIN ...
    ON a.col1 + b.col2 * c.col4 < d.some_threshold
WHERE a.col1 + b.col2*c.col4 > 0

当计算得到相当多的参与并在同一SELECT内使用多达3-5次时,我真的想在函数或类似函数中重构它以便:

  1. 希望提高性能/利用缓存
  2. 当我稍后意识到我需要更改计算时,避免忘记更新4个计算中的一个。
  3. 我通常在SP中有这些选择。

    有什么想法吗?

3 个答案:

答案 0 :(得分:4)

查询优化器应该已经从性能角度优化了重复的评估。但你当然可以使用CTE来提高可读性/可维护性:

WITH CTE AS
(
    SELECT
        a.col1+b.col2*c.col4 as calc_col1,
        a.col1+b.col2*c.col4 + xxx as calc_col1_PLUS_MORE
    FROM ....
)
SELECT ...
FROM CTE c
INNER JOIN ... d
    ON c.calc_col1 < d.some_threshold
WHERE c.calc_col1 > 0

答案 1 :(得分:3)

您还可以堆叠许多CTE以在层中构建复杂表达式:

WITH CTE AS
(
    SELECT
        a.col1+b.col2*c.col4 as calc_col1
    FROM ....
),
CTE2 AS (
    SELECT CTE.*
        ,calc_col1 + xxx as calc_col1_PLUS_MORE
    FROM CTE
)
SELECT ...
FROM CTE2 c
INNER JOIN ... d
    ON c.calc_col1 < d.some_threshold
WHERE c.calc_col1 > 0

答案 2 :(得分:2)

您还可以保留计算字段,甚至索引它们。

如果计算主要在不同的表之间进行,请尝试索引视图。