¿Es posible usar la cláusula SELECT INTO con UNION [ALL]?

154

En SQL Server, esto inserta 100 registros, de la tabla Clientes en tmpFerdeen: -

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

¿Es posible hacer un SELECT INTO a través de UNION ALL SELECT: -

SELECT top(100)* 
FROM Customers
UNION All
SELECT top(100)* 
FROM CustomerEurope
UNION All
SELECT top(100)* 
FROM CustomerAsia
UNION All
SELECT top(100)* 
FROM CustomerAmericas

No estoy muy seguro de dónde agregar la cláusula INTO.

Ferdeen
fuente
¿Estás seguro de que necesitas toda la unión?
sfossen
Si. Como los registros son únicos en todas las tablas.
Ferdeen

Respuestas:

214

Esto funciona en SQL Server:

SELECT * INTO tmpFerdeen FROM (
  SELECT top 100 * 
  FROM Customers
  UNION All
  SELECT top 100 * 
  FROM CustomerEurope
  UNION All
  SELECT top 100 * 
  FROM CustomerAsia
  UNION All
  SELECT top 100 * 
  FROM CustomerAmericas
) as tmp
Chris Van Opstal
fuente
1
También funciona SELECT top 100 * EN tmpFerdeen FROM Clientes UNION Todos SELECT top 100 * FROM CustomerEurope UNION Todos SELECT top 100 * FROM CustomerAsia UNION Todos SELECT top 100 * FROM CustomerAmericas (lo siento, no puedo formatear el sql aquí). ¡Gracias!
Ferdeen
77
¿Cuál es el significado de "como tmp"?
Dave
@chrisVanOpstal, ¿por qué has seleccionado los 100 mejores? Cuando seleccionamos todos los registros, da error como: "La cláusula ORDER BY no es válida en vistas, funciones en línea, tablas derivadas, subconsultas y expresiones de tabla comunes, a menos que también se especifique TOP o FOR XML". Por favor, dame alguna solución.
ShaileshDev
1
Hola, sobre lo que @Dave preguntó, veo que al eliminar "as tmp" se produce un error "Sintaxis incorrecta esperando como, id o quoted_id". Entonces, ¿para qué se utiliza?
Ravid Goldenberg
44
@Dave, petric: en SQL Server, las tablas temporales necesitan un nombre. Eso es todo. El tmp no cumple ninguna otra función que no sea hacer que la instrucción SQL sea válida. En Oracle SQL, por ejemplo, esto es opcional.
Wouter
130

No necesita una tabla derivada para esto.

Solo pon el INTOdespués del primeroSELECT

SELECT top(100)* 
INTO tmpFerdeen
FROM Customers
UNION All
SELECT top(100)* 
FROM CustomerEurope
UNION All
SELECT top(100)* 
FROM CustomerAsia
UNION All
SELECT top(100)* 
FROM CustomerAmericas
Martin Smith
fuente
2
No estoy de acuerdo: aunque la respuesta anterior también es correcta, la respuesta aceptada es más clara en su intención
endurium
5
SELECT * INTO tmpFerdeen FROM 
(SELECT top(100)*  
FROM Customers 
UNION All 
SELECT top(100)*  
FROM CustomerEurope 
UNION All 
SELECT top(100)*  
FROM CustomerAsia 
UNION All 
SELECT top(100)*  
FROM CustomerAmericas) AS Blablabal

Este "Blablabal" es necesario

usuario1006743
fuente
1

Para consultas de MS Access, esto funcionó:

SELECT * INTO tmpFerdeen FROM( 
    SELECT top(100) *
    FROM Customers 
UNION All 
    SELECT top(100) *  
    FROM CustomerEurope 
UNION All 
    SELECT top(100) *  
    FROM CustomerAsia 
UNION All 
    SELECT top(100) *  
    FROM CustomerAmericas
) 

Esto NO funcionó en MS Access

SELECT top(100) * 
  INTO tmpFerdeen
  FROM Customers
UNION All
  SELECT top(100) * 
  FROM CustomerEurope
UNION All
  SELECT top(100) * 
  FROM CustomerAsia
UNION All
  SELECT top(100) * 
  FROM CustomerAmericas
Poli
fuente
1

Lo haría así:

SELECT top(100)* into #tmpFerdeen
FROM Customers

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerEurope

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAsia

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAmericas
Praveen R
fuente
0

El desafío que veo con la solución:

FROM( 
SELECT top(100) *
    FROM Customers 
UNION
    SELECT top(100) *  
    FROM CustomerEurope 
UNION 
    SELECT top(100) *  
    FROM CustomerAsia 
UNION
    SELECT top(100) *  
    FROM CustomerAmericas
)

es que esto crea un conjunto de datos en ventana que residirá en la RAM y en conjuntos de datos más grandes, esta solución creará graves problemas de rendimiento, ya que primero debe crear la partición y luego usará la partición para escribir en la tabla temporal.

Una mejor solución sería la siguiente:

SELECT top(100)* into #tmpFerdeen
FROM Customers

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerEurope

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAsia

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAmericas

para seleccionar insertar en la tabla temporal y luego agregar filas adicionales. Sin embargo, el inconveniente aquí es si hay filas duplicadas en los datos.

La mejor solución sería la siguiente:

Insert into #tmpFerdeen
SELECT top(100)* 
FROM Customers
UNION
SELECT top(100)* 
FROM CustomerEurope
UNION
SELECT top(100)* 
FROM CustomerAsia
UNION
SELECT top(100)* 
FROM CustomerAmericas

Este método debería funcionar para todos los propósitos que requieren filas distintas. Sin embargo, si desea que las filas duplicadas simplemente cambien UNION por UNION ALL

¡La mejor de las suertes!

Chris Peterson
fuente
-1

Tal vez intente esto?

SELECT * INTO tmpFerdeen (
SELECT top(100)* 
FROM Customers
UNION All
SELECT top(100)* 
FROM CustomerEurope
UNION All
SELECT top(100)* 
FROM CustomerAsia
UNION All
SELECT top(100)* 
FROM CustomerAmericas)
Ryan
fuente
Falta el alias de tabla requerido (y si se agrega será el mismo que la respuesta aceptada)
Martin Smith
-3

Pruebe algo como esto: cree la tabla de objetos final, tmpFerdeen con la estructura de la unión.

Luego

INSERT INTO tmpFerdeen (
SELECT top(100)* 
FROM Customers
UNION All
SELECT top(100)* 
FROM CustomerEurope
UNION All
SELECT top(100)* 
FROM CustomerAsia
UNION All
SELECT top(100)* 
FROM CustomerAmericas
)
achinda99
fuente
En SQL Server, las tablas temporales se crean sobre la marcha. Me gustaría hacer esto sin crear una tabla final de objetos. Gracias.
Ferdeen