Reputation: 45
I'm trying to work out why my union queries are giving me type conversion errors
I am trying to create a report that has to be formatted in a way that multiple union queries seems like the easiest option. Essentially I want an output that shows the key column, and then a row for each other column, and the value for that column, so it would kind of look like this:
Key1 Column1 Value
Key1 Column2 Value
Key2 Column1 Value
Key2 Column2 Value
I'm doing this for about 40 columns though, so its a lot of select statements.
All of my select statements are structured the same:
SELECT tb1.Key AS 'Key', 'Column1' AS 'Column', tb1.Column1 AS 'Value'
union
SELECT tb1.Key AS 'Key', 'Column2' AS 'Column', tb1.Column2 AS 'Value'
etc
When running all of the queries individually I have no issue, but when I try to run all, of them I get an issue converting various strings to type int.
In order to try rectifying this I've tried casting every 'value' column as NVARCHAR and I still get an error that some of the strings are trying to be converted to type int, but I'm not sure why that is.
Upvotes: 0
Views: 2958
Reputation: 1269463
The problem is that the columns for a union
need to be of the same type. Typically, you can store values as strings.
More importantly, you don't need union
for this. SQL Server supports lateral joins using the apply
keyword. This is simpler to express as:
select tb1.key, v.column, v.value
from tb1 cross apply
(values ('Column1', convert(nvarchar(max), tb1.Column1),
('Column2', convert(nvarchar(max), tb1.Column2),
. . .
) v(column, value);
Upvotes: 1
Reputation: 3823
Generally when doing a UNION
, the data types of the columns of your result set will be determined by the first query that executes or returns rows. So, if you're not sure which queries in the UNIONs
return data you should CAST
all your columns explicitly. Something like:
SELECT
CAST(tb1.Key AS INTEGER) AS 'Key',
CAST('Column1' AS VARCHAR(100)) AS 'Column',
CAST(tb1.Column1 AS VARCHAR(100)) AS 'Value'
FROM MyTableA AS tb1
UNION
SELECT
CAST(tb1.Key AS INTEGER) AS 'Key',
CAST('Column1' AS VARCHAR(100)) AS 'Column',
CAST(tb1.Column1 AS VARCHAR(100)) AS 'Value'
FROM MyTableB AS tb1
If your UNIONs
are simple SELECTs
from the same table, it shouldn't be a problem. But the issue may come up when some rows return NULL
values and data types may not be what you expect.
Upvotes: 2