我需要从复杂的select查询中创建一些连接列,这是三个选择
的并集SELECT C1,C2, ... FROM Source1
UNION
SELECT C1,C2,... FROM Source2
UNION
SELECT C1,C2 from Source3
现在,我没有在所有三个select语句中重复我的新列的生成逻辑,而是考虑使用表变量来临时存储联合结果,并在表变量的select中添加我的列。像
这样的东西DECLARE @tv TABLE
(C1 varchar(max),
C2 varchar(max)
.
.
.)
INSERT INTO @tv
SELECT C1,C2, ... FROM Source1
UNION
SELECT C1,C2,... FROM Source2
UNION
SELECT C1,C2 from Source3
SELECT
C1,
C2,
CASE WHEN ...
ELSE ''
END CN
FROM @tv
我已经阅读了有关使用表变量时要注意的性能注意事项。上面的查询有时可能会生成几千行,但在大多数情况下会生成几百行。在这种情况下切换到临时变量更好吗? UNION SELECT语句是否仍能并行运行?
答案 0 :(得分:5)
将列生成逻辑放在一个地方是个好主意。我只想用子查询做到这一点:
SELECT s.*,
(CASE WHEN ...
ELSE ''
END) as CN
FROM (SELECT C1,C2, ... FROM Source1
UNION ALL
SELECT C1,C2,... FROM Source2
UNION ALL
SELECT C1,C2 from Source3
) s;
注意:使用UNION ALL
代替UNION
,除非您特别希望产生删除重复项的开销。
答案 1 :(得分:3)
另一种选择是使用CTE,以及您对此的描述方式,这正是CTE的用途:
;WITH cte as
(
SELECT C1,C2, ... FROM Source1
UNION ALL
SELECT C1,C2,... FROM Source2
UNION ALL
SELECT C1,C2 from Source3
)
SELECT cte.*,
(CASE WHEN ...
ELSE ''
END) as CN
FROM cte;
但CTE与表格变量与临时表格有关的一些事项:
( tl; dr: CTE可在单个查询中重复使用,表变量和临时表可在许多查询中重用,并具有一些不同的内存/索引功能。)
INSERT
之后,临时变量和表变量都可以在其上运行其他DML语句 - 如果您需要更新/删除/插入可以工作的更多数据。 CTE无法做到这一点(如果您在CTE上运行DML,它将插入/更新/删除基础表)。