Ist es möglich, die SELECT INTO-Klausel mit UNION [ALL] zu verwenden?

154

In SQL Server werden 100 Datensätze aus der Customers-Tabelle in tmpFerdeen eingefügt: -

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

Ist es möglich, eine SELECT INTO innerhalb einer UNION ALL SELECT durchzuführen: -

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

Ich bin mir nicht sicher, wo ich die INTO-Klausel hinzufügen soll.

Ferdeen
quelle
Bist du sicher, dass du die Gewerkschaft alle brauchst?
Sfossen
Ja. Da Datensätze in allen Tabellen eindeutig sind.
Ferdeen

Antworten:

214

Dies funktioniert 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
Chris Van Opstal
quelle
1
Auch dies funktioniert SELECT Top 100 * IN tmpFerdeen FROM Kunden UNION Alle SELECT Top 100 * FROM CustomerEurope UNION Alle SELECT Top 100 * FROM CustomerAsia UNION Alle SELECT Top 100 * FROM CustomerAmericas (leider kann das SQL hier nicht formatiert werden). Vielen Dank!
Ferdeen
7
Welche Bedeutung hat "as tmp"?
Dave
@chrisVanOpstal, warum hast du die Top 100 ausgewählt? Wenn wir alle Datensätze auswählen, wird der Fehler angezeigt: "Die ORDER BY-Klausel ist in Ansichten, Inline-Funktionen, abgeleiteten Tabellen, Unterabfragen und allgemeinen Tabellenausdrücken ungültig, sofern nicht auch TOP oder FOR XML angegeben ist." Bitte geben Sie eine Lösung.
ShaileshDev
1
Hallo, was @Dave gefragt hat, ich sehe, dass das Entfernen von "as tmp" zu einem Fehler führt "Falsche Syntax erwartet as, id oder quote_id". Wofür wird es verwendet?
Ravid Goldenberg
4
@ Dave, petric: In SQL Server müssen temporäre Tabellen einen Namen erhalten. Das ist alles. Der tmp erfüllt keine andere Funktion als die gültige SQL-Anweisung. In Oracle SQL ist dies beispielsweise optional.
Wouter
130

Sie benötigen dafür überhaupt keine abgeleitete Tabelle.

Setzen Sie einfach das INTOnach dem erstenSELECT

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
quelle
2
Ich bin anderer Meinung - obwohl die obige Antwort auch richtig ist, ist die akzeptierte Antwort in ihrer Absicht klarer
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

Dieses "Blablabal" ist notwendig

user1006743
quelle
1

Bei MS Access-Abfragen hat dies funktioniert:

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
) 

Dies funktionierte NICHT 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
Bobby
quelle
1

Ich würde es so machen:

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.
quelle
0

Die Herausforderung, die ich mit der Lösung sehe:

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

ist, dass dadurch ein Datensatz mit Fenster erstellt wird, der sich im RAM befindet. Bei größeren Datensätzen führt diese Lösung zu schwerwiegenden Leistungsproblemen, da zuerst die Partition erstellt werden muss und dann die Partition zum Schreiben in die temporäre Tabelle verwendet wird.

Eine bessere Lösung wäre die folgende:

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

um Einfügen in die temporäre Tabelle auszuwählen und dann zusätzliche Zeilen hinzuzufügen. Der Nachteil hierbei ist jedoch, dass die Daten doppelte Zeilen enthalten.

Die beste Lösung wäre die folgende:

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

Diese Methode sollte für alle Zwecke funktionieren, für die unterschiedliche Zeilen erforderlich sind. Wenn Sie jedoch möchten, dass die doppelten Zeilen einfach die UNION gegen UNION ALL austauschen

Viel Glück!

Chris Peterson
quelle
-1

Vielleicht versuchen Sie das?

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
quelle
Fehlen des erforderlichen Tabellenalias (und falls hinzugefügt, entspricht dies der akzeptierten Antwort)
Martin Smith
-3

Versuchen Sie Folgendes: Erstellen Sie die endgültige Objekttabelle tmpFerdeen mit der Struktur der Union.

Dann

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
quelle
In SQL Server werden temporäre Tabellen im laufenden Betrieb erstellt. Ich möchte dies tun, ohne eine endgültige Objekttabelle zu erstellen. Vielen Dank.
Ferdeen