sql - 我是否被迫使用 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 通常被描述为缓慢(我不知道在何种程度上以及在何种情况下)。
我想单独使用视图,可以吗?(速度更重要)如果没有,那也没关系,我会做以下其中一项。
- 只需保留复制/粘贴的代码
- 为 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)
推荐阅读
- angular - 角度中带有 $ 前缀的变量
- c++ - 多种数据类型的二进制序列化
- websocket - 在 CustomAbstracthandler 中,Modify Httpfield 在 jetty server 11 版本中不起作用
- javascript - 在 JavaScript 中将字符串转换为 base64。btoa 和 atob 已弃用
- python - 如何解释 cx_freeze 的输出以解决运行时模块查找失败
- google-apps-script - 谷歌脚本事件触发器
- vba - 试图从活动的 ppt 幻灯片中删除表格
- php - 如何用php替换json中的值
- python - 如何解析excel数据并将其修改为所需的数据框?
- ios - iOS - navigationController pushViewController 泄漏 vc 但目前没有