Reputation: 669
I need to create some concatenated columns from a complex select query which is a union of three selects
SELECT C1,C2, ... FROM Source1
UNION
SELECT C1,C2,... FROM Source2
UNION
SELECT C1,C2 from Source3
Now, instead of repeating the generation logic of my new column in all the three select statements, I thought of using a table variable to temporarily store the union results and add my column in a select from the table variable. So something like
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
I have read about performance considerations to be aware of when using table variables. The query above may sometimes generate a few thousand rows but on most occasions will generate a few hundred. Is it better to switch to temporary variable in this case? Will the UNION SELECT statements still be able to run in parallel?
Upvotes: 2
Views: 1766
Reputation: 21641
Another option would be using a CTE, and the way you're describing this, this is pretty much what CTEs are for:
;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;
But a few things to consider around CTE vs table var vs temp table:
(tl;dr: CTEs are reusable within a single query, table variables and temp tables are reusable within many queries and have some different memory/indexing capabilities.)
INSERT
- if you need to update/delete/insert more data in them that can work. CTEs can't do that (if you run DML on a CTE, it will insert/update/delete the underlying table(s)).Upvotes: 3
Reputation: 1269873
Putting the column generation logic in one place is a good idea. I would just do this with a subquery:
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;
Note: Use UNION ALL
instead of UNION
, unless you specifically want to incur the overhead of removing duplicates.
Upvotes: 5