我是否被迫使用 CTE 或存储过程而不是视图?

问题描述

我想减少代码的大小,并希望尽可能快地运行

我在同一个 SELECT 中多次复制粘贴了一个 CASE 表达式。这是多余的,可能会多次运行 switch 而不是一次,使它比它应该运行的更慢(或者不是吗?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 通常被描述为缓慢(我不知道在何种程度上以及在何种情况下)。

我想单独使用一个视图,可以吗? (速度更重要)如果没有,那也没关系,我就做下面的一个

  • 只需保留复制/粘贴的代码
  • 对 case 表达式使用存储过程(添加到使数据库混乱的许多过程中)
  • 仅使用 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','c') THEN 'something'
                ELSE 'something_else'
            END = 'Second thing to compare with'
        THEN [return_Second],'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
       

解决方法

执行此操作的最佳方法是将表达式放在 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)
,

就这么简单:

SELECT 
    CaseColumn + 1 AS a,CaseColumn + 2 AS b,CaseColumn + 3 AS c,CaseColumn + 4 AS d
FROM (
    SELECT
        /* 20 lines case expression */ AS CaseColumn
    FROM some_table
)