Чи можна використовувати пункт SELECT INTO з UNION [ALL]?


154

У SQL Server це вставляє 100 записів із таблиці Клієнти в tmpFerdeen: -

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

Чи можна зробити ВИБІР ВІД СІЛЮ ВСІЙ ВИБІР: -

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

Не надто впевнений, куди додати пункт INTO.


Ви впевнені, що вам потрібен союз?
sfossen

Так. Оскільки записи є унікальними у всіх таблицях.
Фердін

Відповіді:


214

Це працює в 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
Також це працює SELECT top 100 * INTO tmpFerdeen ВІД Клієнтів UNION Усі SELECT top 100 * FROM CustomerEurope UNION Всі SELECT top 100 * FROM CustomerAsia UNION Усі SELECT top 100 * From CustomerAmericas (вибачте, тут не можна форматувати sql). Дякую!
Фердін

7
Яке значення "як tmp"?
Дейв

@chrisVanOpstal, чому ти вибрав топ-100? Коли ми вибираємо всі записи, вона видає помилку, оскільки - "ЗАМОВЛЮВАТИ БУДЬ недійсний у представленнях, вбудованих функціях, похідних таблицях, підзапитах та загальних виразах таблиць, якщо не вказано також TOP або FOR XML." Будь ласка, дайте якесь рішення.
ShaileshDev

1
Привіт про те, що @Dave запитав, я бачу, що видалення "as tmp" призводить до помилки "Неправильний синтаксис очікує як, id або quoted_id". То для чого він використовується?
Ravid Goldenberg

4
@Dave, petric: у SQL Server тимчасовим таблицям потрібно вказати ім’я. Це все. Tmp не виконує жодної іншої функції, крім того, щоб зробити оператор SQL дійсним. Наприклад, у Oracle SQL це необов’язково.
Wouter

130

Для цього вам взагалі не потрібна похідна таблиця.

Просто поставте INTOпісля першогоSELECT

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
Я не погоджуюся - хоча вищенаведена відповідь також є правильною, прийнята відповідь є чіткішою у її намірі
ендурій

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

Цей "Блаблабал" необхідний


1

Для запитів MS Access це спрацювало:

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
) 

Це не працювало в 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

Я б це зробив так:

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

Проблема, яку я бачу у вирішенні:

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

полягає в тому, що це створює віконний набір даних, який буде знаходитися в оперативній пам'яті, а на більших наборах даних це рішення створить серйозні проблеми з продуктивністю, оскільки він повинен спочатку створити розділ, а потім буде використовувати розділ для запису в таблицю темп.

Кращим рішенням було б таке:

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

щоб вибрати вставку в таблицю темп, а потім додати додаткові рядки. Однак зворотний зв'язок тут є, якщо в даних є якісь повторювані рядки.

Найкращим рішенням було б таке:

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

Цей метод повинен працювати для всіх цілей, які вимагають чітких рядків. Якщо ви хочете, щоб повторювані рядки просто замінили UNION на UNION ALL

Удачі!


-1

Може, спробувати це?

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)

Пропущений необхідний псевдонім таблиці (і якщо його буде додано, буде таким самим, як і прийняту відповідь)
Мартін Сміт

-3

Спробуйте щось подібне: Створіть кінцеву таблицю об'єктів, tmpFerdeen зі структурою об'єднання.

Тоді

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
)

У SQL Server тимчасові таблиці створюються з льоту. Я б хотів це зробити, не створюючи остаточної таблиці об'єктів. Дякую.
Фердін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.