СОЗДАТЬ ТАБЛИЦУ КАК ВЫБРАТЬ В

16

PostgreSQL поддерживает, CREATE TABLE ASи SELECT INTOкогда я использую оба?

CREATE TABLE AS - определить новую таблицу из результатов запроса

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

CREATE TABLE ASимеет некоторое сходство с созданием представления, но на самом деле оно совершенно иное: оно создает новую таблицу и оценивает запрос только один раз, чтобы изначально заполнить новую таблицу. Новая таблица не будет отслеживать последующие изменения в исходных таблицах запроса. Напротив, представление переоценивает свое определяющее SELECTутверждение всякий раз, когда его запрашивают.

А потом.

SELECT INTO - определить новую таблицу из результатов запроса

SELECT INTOсоздает новую таблицу и заполняет ее данными, вычисленными по запросу. Данные не возвращаются клиенту, как это обычно бывает SELECT. Столбцы новой таблицы имеют имена и типы данных, связанные с выходными столбцами SELECT.

Эван Кэрролл
источник

Ответы:

15

Без объяснения, всегда используйте CREATE TABLE ASбез исключения. Внизу каждого под примечаниями это проясняется,

Примечания для SELECT INTO,

CREATE TABLE ASфункционально похож на SELECT INTO. CREATE TABLE ASявляется рекомендуемым синтаксисом, поскольку эта форма SELECT INTOнедоступна в ECPG или PL / pgSQL, поскольку они по-разному интерпретируют предложение INTO. Кроме того, CREATE TABLE ASпредлагает расширенный набор функций, предоставляемых SELECT INTO.

Примечания для CREATE TABLE AS,

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

Кроме того, в разделе совместимости документов SELECT INTOидет еще дальше,

Стандарт SQL использует SELECT INTOпредставление значений в скалярных переменных хост-программы вместо создания новой таблицы. Это действительно используется в ECPG (см. Главу 34) и PL / pgSQL (см. Главу 41). Использование PostgreSQL SELECT INTOдля представления создания таблиц является историческим. Лучше всего использовать CREATE TABLE ASдля этого в новом коде.

Итак, мы имеем,

  1. PostgreSQL считает, что это сбивает с толку, потому SELECT INTOчто другие вещи в контекстах доступны только в PL / pgSQL и ECPG.
  2. CREATE TABLEподдерживает больше функций (я полагаю, они имеют в виду WITH OIDS, и TABLESPACE, IF NOT EXISTS).
  3. SELECT INTO для создания таблицы "не рекомендуется".

Как примечание, синтаксис для CTAS с CTE может выглядеть немного странно. , а также SELECT INTO может быть своего рода удержание над QUELRETRIEVE INTO . QUEL был предшественником SQL, который использовался предшественником PostgreSQL (INGRES).

Эван Кэрролл
источник
1

Я заметил еще одну вещь, которая отсутствует в принятом ответе. Использование CREATE TABLE ASсохраняет атрибут nullable каждого столбца, который, похоже, игнорируется SELECT INTO.

Только на этой основе я бы порекомендовал CREATE TABLE AS. Обычный вариант использования обоих операторов - загрузка данных из долго выполняющегося запроса в таблицу без блокировки этой таблицы на время выполнения запроса. Вы создаете временную таблицу с помощью одной из приведенных выше команд, помещаете туда результаты длительного выполнения запроса, а затем вставляете эти результаты в исходную таблицу. Сохранение атрибута nullable в вашей временной таблице уменьшает шансы вашей второй вставки на ошибку.

Протестировано это на PG 11, так что, возможно, более новая функция, так как на этот вопрос был дан ответ.

shrumm
источник
Длительный запрос не блокирует таблицу. Поэтому мотивация использовать CTAS по этой причине бесполезна
a_horse_with_no_name