Est-il possible d'utiliser la clause SELECT INTO avec UNION [ALL]?

154

Dans SQL Server, cela insère 100 enregistrements, de la table Clients dans tmpFerdeen: -

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

Est-il possible de faire un SELECT INTO sur un 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

Je ne sais pas trop où ajouter la clause INTO.

Ferdeen
la source
Êtes-vous sûr que vous avez tous besoin du syndicat?
sfossen le
Oui. Comme les enregistrements sont uniques dans toutes les tables.
Ferdeen le

Réponses:

214

Cela fonctionne dans 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
la source
1
Cela fonctionne aussi SELECT top 100 * DANS tmpFerdeen FROM Customers UNION Tous SELECT top 100 * FROM CustomerEurope UNION Tous SELECT top 100 * FROM CustomerAsia UNION Tous SELECT top 100 * FROM CustomerAmericas (désolé, impossible de formater le sql ici). Merci!
Ferdeen le
7
Quelle est la signification de "as tmp"?
Dave
@chrisVanOpstal, pourquoi avez-vous sélectionné le top 100? Lorsque nous sélectionnons tous les enregistrements, cela donne une erreur comme- "La clause ORDER BY n'est pas valide dans les vues, les fonctions en ligne, les tables dérivées, les sous-requêtes et les expressions de table communes, à moins que TOP ou FOR XML ne soit également spécifié.". Veuillez donner une solution.
ShaileshDev
1
Salut à propos de ce que @Dave a demandé, je vois que la suppression du "as tmp" entraîne une erreur "Syntaxe incorrecte attendue comme, id ou quoted_id". Alors à quoi sert-il?
Ravid Goldenberg
4
@Dave, petric: dans SQL Server, il faut donner un nom aux tables temporaires. C'est tout. Le tmp ne remplit aucune autre fonction que de rendre l'instruction SQL valide. Sur Oracle SQL, par exemple, cela est facultatif.
Wouter
130

Vous n'avez pas du tout besoin d'une table dérivée pour cela.

Juste mettre INTOaprès le premierSELECT

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
la source
2
Je ne suis pas d'accord - bien que la réponse ci-dessus soit également correcte, la réponse acceptée est plus claire dans son intention
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

Ce "Blablabal" est nécessaire

user1006743
la source
1

Pour les requêtes MS Access, cela a fonctionné:

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
) 

Cela n'a PAS fonctionné dans 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
Policier
la source
1

Je le ferais comme ceci:

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
la source
0

Le défi que je vois avec la solution:

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

est que cela crée un ensemble de données fenêtré qui résidera dans la RAM et sur des ensembles de données plus volumineux, cette solution créera de graves problèmes de performances car elle doit d'abord créer la partition, puis elle utilisera la partition pour écrire dans la table temporaire.

Une meilleure solution serait la suivante:

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

pour sélectionner insérer dans la table temporaire, puis ajouter des lignes supplémentaires. Cependant, le problème ici est s'il y a des lignes en double dans les données.

La meilleure solution serait la suivante:

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

Cette méthode devrait fonctionner à toutes les fins nécessitant des lignes distinctes. Si, cependant, vous voulez les lignes dupliquées, remplacez simplement UNION par UNION ALL

Bonne chance!

Chris Peterson
la source
-1

Essayez peut-être ceci?

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
la source
Il manque l'alias de table requis (et s'il est ajouté, il sera le même que la réponse acceptée)
Martin Smith
-3

Essayez quelque chose comme ceci: Créez la table d'objets finale, tmpFerdeen avec la structure de l'union.

ensuite

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
la source
Dans SQL Server, les tables temporaires sont créées à la volée. Je voudrais faire cela sans créer une table d'objets finale. Merci.
Ferdeen le