Неоднозначный столбец в PostgreSQL UPSERT (CTE с возможностью записи), использующий одну таблицу для обновления другой

У меня есть таблица с именем users_import, в которую я анализирую и импортирую файл CSV. Используя эту таблицу, я хочу ОБНОВИТЬ свою таблицу users, если пользователь уже существует, или ВСТАВИТЬ, если она еще не существует. (На самом деле это очень упрощенный пример чего-то гораздо более сложного, что я пытаюсь сделать.)

Я пытаюсь сделать что-то очень похожее на это: https://stackoverflow.com/a/8702291/912717

Вот определения таблицы и запрос:

CREATE TABLE users (
    id INTEGER NOT NULL UNIQUE PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE users_import (
    id INTEGER NOT NULL UNIQUE PRIMARY KEY,
    name TEXT NOT NULL
);

WITH upsert AS (
    UPDATE users AS u
    SET
        name = i.name
    FROM users_import AS i
    WHERE u.id = i.id
    RETURNING *
)
INSERT INTO users (name)
    SELECT id, name 
    FROM users_import
    WHERE NOT EXISTS (SELECT 1 FROM upsert WHERE upsert.id = users_import.id);

Этот запрос дает эту ошибку:

psql:test.sql:23: ERROR:  column reference "id" is ambiguous
LINE 11:  WHERE NOT EXISTS (SELECT 1 FROM upsert WHERE upsert.id = us...
                                                       ^

Почему id неоднозначен и что его вызывает?


person Ian Timothy    schedule 14.02.2013    source источник


Ответы (1)


RETURNING * в предложении WITH upsert... содержит все столбцы из users и все столбцы из объединенной таблицы users_import. Таким образом, в результате есть два столбца с именами id и два столбца с именами name, отсюда и двусмысленность при ссылке на upsert.id.

Чтобы избежать этого, используйте RETURNING u.id, если вам не нужны остальные столбцы.

person Daniel Vérité    schedule 14.02.2013
comment
Гах. Так просто. Спасибо. - person Ian Timothy; 15.02.2013