Инструкция SELECT INTO в T-SQL или как создать таблицу на основе SQL запроса?

Если у Вас возникала необходимость сохранить результирующий набор данных, который вернул SQL запрос, то данная статья будет Вам интересна, так как в ней мы рассмотрим инструкцию SELECT INTO, с помощью которой в Microsoft SQL Server можно создать новую таблицу и заполнить ее результатом SQL запроса.

Начнем мы, конечно же, с описания самой инструкции SELECT INTO, а затем перейдем к примерам.

Инструкция SELECT INTO в Transact-SQL

SELECT INTO – инструкция в языке в T-SQL, которая создает новую таблицу и вставляет в нее результирующие строки из SQL запроса. Структура таблицы, т.е. количество и имена столбцов, а также типы данных и свойства допустимости значений NULL, будут на основе столбцов (выражений), указанных в списке выбора из источника в инструкции SELECT. Обычно инструкция SELECT INTO используется для объединения в одной таблице данных из нескольких таблиц, представлений, включая какие-то расчетные данные.

Для того чтобы использовать инструкцию SELECT INTO требуется разрешение CREATE TABLE в базе данных, в которой будет создана новая таблица.

Инструкция SELECT INTO имеет два аргумента:

  • new_table — имя новой таблицы;
  • filegroup – файловая группа. Если аргумент не указан, то используется файловая группа по умолчанию. Данная возможность доступна начиная с Microsoft SQL Server 2017.

Важные моменты про инструкцию SELECT INTO

  • Инструкцию можно использовать для создания таблицы на текущем сервере, на удаленном сервере создание таблицы не поддерживается;
  • Заполнить данными новую таблицу можно как с текущей базы данных и текущего сервера, так и с другой базы данных или с удаленного сервера. Например, указывать полное имя базы данных в виде база_данных.схема.имя_таблицы или в случае с удаленным сервером, связанный_сервер.база_данных.схема.имя_таблицы;
  • Столбец идентификаторов в новой таблице не наследует свойство IDENTITY, если: инструкция содержит объединение (JOIN, UNION), предложение GROUP BY, агрегатную функцию, также, если столбец идентификаторов является частью выражения, получен из удаленного источника данных или встречается более чем один раз в списке выбора. Во всех подобных случаях столбец идентификаторов не наследует свойство IDENTITY и создается как NOT NULL;
  • С помощью инструкции SELECT INTO нельзя создать секционированную таблицу, даже если исходная таблица является секционированной;
  • В качестве новой таблицы можно указать обычную таблицу, а также временную таблицу, однако нельзя указать табличную переменную или возвращающий табличное значение параметр;
  • Вычисляемый столбец, если такой есть в списке выбора инструкции SELECT INTO, в новой таблице он становится обычным, т.е. не вычисляемым;
  • SELECT INTO нельзя использовать вместе с предложением COMPUTE;
  • С помощью SELECT INTO в новую таблицу не переносятся индексы, ограничения и триггеры, их нужно создавать дополнительно, после выполнения инструкции, если они нужны;
  • Предложение ORDER BY не гарантирует, что строки в новой таблице будут вставлены в указанном порядке.
  • В новую таблицу не переносится атрибут FILESTREAM. Объекты BLOB FILESTREAM в новой таблице будут как объекты BLOB типа varbinary(max) и имеют ограничение в 2 ГБ;
  • Объем данных, записываемый в журнал транзакций во время выполнения операций SELECT INTO, зависит от модели восстановления. В базах данных, в которых используется модель восстановления с неполным протоколированием, и простая модель, массовые операции, к которым относится SELECT INTO, минимально протоколируются. За счет этого инструкция SELECT INTO может оказаться более эффективней, чем отдельные инструкции по созданию таблицы и инструкции INSERT по заполнение ее данными.

Примеры использования SELECT INTO

Все примеры я буду выполнять в СУБД Microsoft SQL Server 2016 Express.

Исходные данные

Для начала давайте создадим две таблицы и заполним их данными, эти таблицы мы и будем объединять в примерах.

   
   CREATE TABLE TestTable(
        [ProductId] [INT] IDENTITY(1,1) NOT NULL,
        [CategoryId] [INT] NOT NULL,
        [ProductName] [VARCHAR](100) NOT NULL,
        [Price] [money] NULL
   ) ON [PRIMARY]

   GO

   CREATE TABLE TestTable2(
        [CategoryId] [INT] IDENTITY(1,1) NOT NULL,
        [CategoryName] [VARCHAR](100) NOT NULL
   ) ON [PRIMARY]

   GO

   INSERT INTO TestTable
        VALUES (1,'Клавиатура', 100),
                   (1, 'Мышь', 50),
                   (2, 'Телефон', 300)
   GO

   INSERT INTO TestTable2
        VALUES ('Комплектующие компьютера'),
                   ('Мобильные устройства')
   GO
                  
   SELECT * FROM TestTable

   SELECT * FROM TestTable2

Скриншот 1

Пример 1 – Создание таблицы с помощью инструкции SELECT INTO с объединением данных

Давайте представим, что нам необходимо объединить две таблицы и сохранить полученный результат в новую таблицу (например, нам нужно получить товары с названием категории, к которой они относятся).

   
   --Операция SELECT INTO
   SELECT T1.ProductId, T2.CategoryName, T1.ProductName, T1.Price
   INTO TestTable3 
   FROM TestTable T1
   LEFT JOIN TestTable2 T2 ON T1.CategoryId = T2.CategoryId

   --Выборка данных из новой таблицы
   SELECT * FROM TestTable3


Скриншот 2

В итоге мы создали таблицу с названием TestTable3 и заполнили ее объединёнными данными.

Пример 2 – Создание временной таблицы с помощью инструкции SELECT INTO с группировкой данных

Сейчас давайте, допустим, что нам нужны сгруппированные данные, например, информация о количестве товаров в определенной категории, при этом эти данные нам нужно сохранить во временную таблицу, например, эту информацию мы будем использовать только в SQL инструкции, поэтому нам нет необходимости создавать полноценную таблицу.

   
   --Создаем временную таблицу (#TestTable) с помощью инструкции SELECT INTO
   SELECT T2.CategoryName, COUNT(T1.ProductId) AS CntProduct
   INTO #TestTable
   FROM TestTable T1
   LEFT JOIN TestTable2 T2 ON T1.CategoryId = T2.CategoryId
   GROUP BY T2.CategoryName

   --Выборка данных из временной таблицы
   SELECT * FROM #TestTable

Скриншот 3

Как видим, у нас получилось создать временную таблицу #TestTable и заполнить ее сгруппированными данными.

Вот мы с Вами и рассмотрели инструкцию SELECT INTO в языке T-SQL, в своей книге «Путь программиста T-SQL» я подробно рассказываю про все конструкции языка T-SQL (рекомендую почитать), а у меня на этом все, пока!

Понравилась статья? Поделиться с друзьями:
Заметки IT специалиста
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:
Нажимая на кнопку «Отправить комментарий», я даю согласие на обработку персональных данных и принимаю политику конфиденциальности.