views:

101

answers:

6

I wanted to do an insert into with a union, and someone suggested this:

SELECT x INTO ##temp
FROM (SELECT x FROM y UNION ALL SELECT x FROM z) UN

It works, but what is the UN? Unfortunately, Googling for "t-sql un" isn't very helpful :p

Note: I found out that you can just do SELECT x INTO ##temp FROM y UNION ALL SELECT x FROM b but I'm still curious about UN.

EDIT: Ok, so it's an alias, but why is it required to make this work? If I remove it, it won't execute.

+10  A: 

It's not a keyword. It's an alias. Any string could have been used there instead of "UN".

In more complete form, it is:

SELECT x INTO ##temp
FROM (SELECT x FROM y UNION ALL SELECT x FROM z) AS UN

@Tomalak is correct. In this case, the alias is required. Without the alias, the error is:

Msg 102, Level 15, State 1, Line 2 Incorrect syntax near ')'.

I simplified the query a bit and used the AdventureWorks database:

SELECT * INTO ##temp
FROM (SELECT * FROM Person.Address) 

this receives the error above. In contrast:

SELECT * INTO ##temp
FROM Person.Address

works just fine. An alternative is

;WITH UN AS
(
    SELECT * FROM Person.Address
)
SELECT * INTO ##temp
FROM UN
John Saunders
Any idea why it's required? If I don't add the alias, it won't execute.
Brendan Long
It is not required in general. It might be referenced by some other part of the query, that's all.
John Saunders
For mysql it is required, you have to give tables aliases if they're from a subquery. But I don't think SQLServer has the same requirement.
Malfist
@Brendan: In this case the alias it definitely *is* required. Since SELECT cannot work with an anonymous table, you must give the result of the inner query a name. In cases where you select from actual tables or views, they already have a name, so giving them an alias is convenient sometimes, but optional.
Tomalak
@Malfist: SQL Server and MySQL are the only databases I've used that have an error for an un-aliased derived table/inline view.
OMG Ponies
+3  A: 

It is an alias in this context. There is no un T-SQL command. You can then reference your fields with that.

SELECT un.x INTO ##temp
FROM (SELECT x FROM y UNION ALL SELECT x FROM z) UN
Dustin Laine
+1  A: 

In this case, UN is the alias for the result set of the subquery (the (SELECT x FROM y UNION ALL SELECT x FROM z)). You can replace UN with whatever you like as long as it's not going to confuse the parser.

ngroot
+1  A: 

All that does is alias the (SELECT x FROM y UNION ALL SELECT x FROM z) to "UN"

Eric H
A: 

An alias/correlation name gives the result set a temporary name so that it can be referenced elsewhere in the query. This example shows that the alias is required to be able to reference the fields in the sub queries in the select and join clauses. If the sub-queries did not have aliases the server would not know what table to get field 'y' from. The aliases are required to distinguish the two different roles of the sub-queries.

select A.*, B.y
from 
(select id, f, k, y from Table1) A
join
(select id, t, y, s from Table2) B
on A.id = B.id
GluedHands
+4  A: 

It is required becasue this is a derived table and a derived tables are required to have a name. Won't this work? I don't see that you need the derived table.

SELECT x 
INTO #Temp
FROM y 
UNION ALL 
SELECT x 
FROM z

I changed to a regular temp table as global ones are usually a bad idea as other connection can affect them. If you really need one then use it, otherwise be very careful of using gloabl temp tables.

HLGEM