Czy jest możliwe użycie klauzuli SELECT INTO z UNION [ALL]?

154

W SQL Server powoduje to wstawienie 100 rekordów z tabeli Klienci do tmpFerdeen: -

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

Czy jest możliwe wykonanie SELECT INTO w całej UNII 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

Nie jestem pewien, gdzie dodać klauzulę INTO.

Ferdeen
źródło
Czy na pewno potrzebujesz całej unii?
sfossen
Tak. Ponieważ rekordy są unikalne we wszystkich tabelach.
Ferdeen

Odpowiedzi:

214

Działa to w 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
źródło
1
Również to działa. SELECT top 100 * INTO tmpFerdeen od klientów UNION Wszystkie SELECT top 100 * FROM CustomerEurope UNION Wszystkie SELECT top 100 * FROM CustomerAsia UNION Wszystkie SELECT top 100 * FROM CustomerAmericas (przepraszam, że nie można tutaj sformatować sql). Dzięki!
Ferdeen
7
Jakie jest znaczenie „as tmp”?
Dave
@chrisVanOpstal, dlaczego wybrałeś 100 najlepszych? Kiedy wybieramy wszystkie rekordy, wyświetla się błąd jako - „Klauzula ORDER BY jest niepoprawna w widokach, funkcjach wbudowanych, tabelach pochodnych, podzapytaniach i typowych wyrażeniach tabel, chyba że określono również TOP lub FOR XML.”. Proszę podać rozwiązanie.
ShaileshDev,
1
Cześć, o co zapytał @Dave. Widzę, że usunięcie „as tmp” powoduje wyświetlenie błędu „Nieprawidłowa składnia oczekiwana jako as, id lub quoted_id”. Więc do czego służy?
Ravid Goldenberg,
4
@Dave, petric: w SQL Server tabelom tymczasowym należy nadać nazwę. To wszystko. Tmp nie pełni żadnej innej funkcji poza nadaniem instrukcji SQL poprawnej. Na przykład w Oracle SQL jest to opcjonalne.
Wouter
130

W ogóle nie potrzebujesz do tego tabeli pochodnej.

Po prostu umieść INTOpo pierwszymSELECT

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
źródło
2
Nie zgadzam się - chociaż powyższa odpowiedź jest również poprawna, przyjęta odpowiedź jest jaśniejsza w swoim zamiarze
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

Ten „Blablabal” jest konieczny

user1006743
źródło
1

W przypadku zapytań MS Access to zadziałało:

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
) 

To NIE zadziałało w 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
Konstabl
źródło
1

Zrobiłbym to tak:

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
źródło
0

Wyzwanie, które widzę w rozwiązaniu:

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

polega na tym, że tworzy to zestaw danych w oknie, który będzie rezydował w pamięci RAM, a przy większych zestawach danych to rozwiązanie spowoduje poważne problemy z wydajnością, ponieważ najpierw musi utworzyć partycję, a następnie użyje partycji do zapisu w tabeli tymczasowej.

Lepszym rozwiązaniem byłoby:

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

aby wybrać wstaw do tabeli tymczasowej, a następnie dodaj dodatkowe wiersze. Jednak wada polega na tym, że w danych występują zduplikowane wiersze.

Najlepszym rozwiązaniem byłoby:

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

Ta metoda powinna działać do wszystkich celów, które wymagają odrębnych wierszy. Jeśli jednak chcesz, aby zduplikowane wiersze po prostu zamień UNION na UNION ALL

Powodzenia!

Chris Peterson
źródło
-1

Może spróbuj tego?

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
źródło
Brakuje wymaganego aliasu tabeli (a jeśli zostanie dodany, będzie taki sam jak zaakceptowana odpowiedź)
Martin Smith
-3

Spróbuj czegoś takiego: Utwórz ostateczną tabelę obiektów, tmpFerdeen ze strukturą unii.

Następnie

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
źródło
W SQL Server tabele tymczasowe są tworzone w locie. Chciałbym to zrobić bez tworzenia ostatecznej tabeli obiektów. Dzięki.
Ferdeen