首页 > 解决方案 > 我是否被迫使用 CTE 或存储过程而不是视图?

问题描述

我想减少我的代码的大小,并有一个运行尽可能快的查询。

我在同一个 SELECT 中多次复制粘贴了一个 CASE 表达式。这是多余的,可能会多次而不是一次运行开关,使其比应有的速度慢(或者不是吗?SQL 图是否检测到冗余代码并重用结果?)

-- My view.
SELECT
    /* 20 lines case expression */ + 1 AS a,
    /* 20 lines case expression */ + 2 AS b,
    /* 20 lines case expression */ + 3 AS c,
    /* 20 lines case expression */ + 4 AS d,
FROM some_table

为了避免重复自己,我想做以下事情:

-- The following code is not valid. It is meant to represent my goal.
SELECT @temp := /* 20 lines case expression */ AS complex
FROM some_table;

SELECT
    @temp + 1 AS a,
    @temp + 2 AS b,
    @temp + 3 AS c,
    @temp + 4 AS d,
FROM some_table

但是您可能知道,用户定义的变量与视图无关。此外,CTE 通常被描述为缓慢(我不知道在何种程度上以及在何种情况下)。

我想单独使用视图,可以吗?(速度更重要)如果没有,那也没关系,我会做以下其中一项。

感谢您的帮助并分享您解决此问题的方法。

更新:

根据您的要求,这是我正在处理的更实际的示例。它基于遗留代码,请不要相信我。

-- It's a simplified example with small alterations.
SELECT
    -- Nothing special ...
    [col_x] AS X,
    [col_y] AS Y,
    [col_z] AS Z,
    -- Then there is this column...
    CASE
        WHEN
            [col_a] + ' ' +
            CASE
                WHEN [col_b] = 'some_code' THEN 'something'
                ELSE 'something_else'
            END + ' ' +
            CASE
                WHEN [col_c] IN ('a', 'b', 'c') THEN 'something'
                ELSE 'something_else'
            END = 'First thing to compare with'
        THEN [return_First],
        WHEN
            [col_a] + ' ' +
            CASE
                WHEN [col_b] = 'some_code' THEN 'something'
                ELSE 'something_else'
            END + ' ' +
            CASE
                WHEN [col_c] IN ('a', 'b', 'c') THEN 'something'
                ELSE 'something_else'
            END = 'Second thing to compare with'
        THEN [return_Second],
        WHEN
            [col_a] + ' ' +
            CASE
                WHEN [col_b] = 'some_code' THEN 'something'
                ELSE 'something_else'
            END + ' ' +
            CASE
                WHEN [col_c] IN ('a', 'b', 'c') THEN 'something'
                ELSE 'something_else'
            END = 'Second thing to compare with'
        THEN [return_Third]
    END AS [Monster Case Expression That Makes Me Cry]
FROM some_table
       

标签: sqlsql-serversql-view

解决方案


最好的方法是将表达式放在一个 中APPLY,这意味着您可以在查询中的任何地方重复使用它:

SELECT
    v1.Temp + 1 AS a,
    v1.Temp + 2 AS b,
    v1.Temp + 3 AS c,
    v1.Temp + 4 AS d,
FROM some_table
CROSS APPLY (VALUES (
    CASE WHEN /* 20 lines case expression */
    END
) ) AS v1(Temp)

推荐阅读