È possibile utilizzare la clausola SELECT INTO con UNION [ALL]?


154

In SQL Server questo inserisce 100 record, dalla tabella Clienti in tmpFerdeen: -

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

È possibile eseguire un SELECT INTO su 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

Non sono sicuro di dove aggiungere la clausola INTO.


Sei sicuro di aver bisogno del sindacato tutto?
sfossen,

Sì. Poiché i record sono unici in tutte le tabelle.
Ferdeen,

Risposte:


214

Funziona in 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

1
Funziona anche SELEZIONA top 100 * INTO tmpFerdeen DA Clienti UNION Tutti SELEZIONA top 100 * DA CustomerEurope UNION Tutti SELECT top 100 * DA CustomerAsia UNION Tutti SELECT top 100 * FROM CustomerAmericas (mi dispiace non poter formattare sql qui). Grazie!
Ferdeen,

7
Qual è il significato di "as tmp"?
Dave,

@chrisVanOpstal, perché hai selezionato i primi 100? Quando selezioniamo tutti i record, viene visualizzato l'errore "La clausola ORDER BY non è valida nelle viste, nelle funzioni incorporate, nelle tabelle derivate, nelle sottoquery e nelle espressioni di tabella comuni, a meno che non venga specificato anche TOP o FOR XML". Per favore, dai una soluzione.
ShaileshDev

1
Ciao a proposito di ciò che ha chiesto @Dave, vedo che la rimozione di "as tmp" genera un errore "Sintassi errata in attesa di come, id o quoted_id". Quindi a cosa serve?
Ravid Goldenberg,

4
@Dave, petric: in SQL Server è necessario assegnare un nome alle tabelle temporanee. È tutto. Tmp non ha altre funzioni se non quella di rendere valida l'istruzione SQL. Su Oracle SQL, ad esempio, questo è facoltativo.
Wouter,

130

Per questo non hai bisogno di una tabella derivata.

Metti il INTOdopo il primoSELECT

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

2
Non sono d'accordo - anche se la risposta sopra è anche corretta, la risposta accettata è più chiara nella sua intenzione
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

Questo "Blablabal" è necessario


1

Per le query di MS Access, ha funzionato:

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
) 

Questo NON ha funzionato in 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

1

Lo farei così:

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

0

La sfida che vedo con la soluzione:

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

è che questo crea un set di dati con finestre che risiederà nella RAM e su set di dati più grandi questa soluzione creerà gravi problemi di prestazioni in quanto deve prima creare la partizione e quindi utilizzerà la partizione per scrivere nella tabella temporanea.

Una soluzione migliore sarebbe la seguente:

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

per selezionare inserire nella tabella temporanea e quindi aggiungere ulteriori righe. Tuttavia, lo svantaggio qui è se ci sono righe duplicate nei dati.

La migliore soluzione sarebbe la seguente:

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

Questo metodo dovrebbe funzionare per tutti gli scopi che richiedono righe distinte. Se, tuttavia, si desidera che le righe duplicate sostituiscano semplicemente UNION con UNION ALL

Buona fortuna!


-1

Forse provare questo?

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)

Manca l'alias della tabella richiesto (e se aggiunto sarà lo stesso della risposta accettata)
Martin Smith,

-3

Prova qualcosa del genere: crea la tabella degli oggetti finale, tmpFerdeen con la struttura dell'unione.

Poi

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
)

In SQL Server le tabelle temporanee vengono create al volo. Vorrei farlo senza creare una tabella degli oggetti finale. Grazie.
Ferdeen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.