我是否被迫使用 CTE 或存储过程而不是视图?
Am I forced to use a CTE or stored procedure instead of a view?
我想减少我的代码的大小并有一个查询 运行 尽可能快。
我在同一个 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 通常被描述为缓慢(我不知道在何种程度上和在何种情况下)。
我想单独使用一个视图,可以吗? (速度更重要)如果不行,那也没关系,我就做下面的一个。
- 只保留copy/pasted代码
- 对 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', '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
最好的方法是将表达式放在 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
)
我想减少我的代码的大小并有一个查询 运行 尽可能快。
我在同一个 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 通常被描述为缓慢(我不知道在何种程度上和在何种情况下)。
我想单独使用一个视图,可以吗? (速度更重要)如果不行,那也没关系,我就做下面的一个。
- 只保留copy/pasted代码
- 对 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', '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
最好的方法是将表达式放在 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
)