Ошибка: ОШИБКА: имя таблицы указано более одного раза

#sql #postgresql

#sql #postgresql

Вопрос:

У меня есть таблица «queued_items». Текущие «user_id» и «item_id» неверны, но хранятся в других таблицах: users.imported_id и items.imported_id

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

 UPDATE queued_items
SET queued_items.user_id = users.id,
    queued_items.item_id = items.id
FROM queued_items
INNER JOIN users ON queued_items.user_id = users.imported_id
INNER JOIN items ON queued_items.item_id = items.imported_id
  

Получение этой ошибки:

 Error : ERROR:  table name "queued_items" specified more than once
  

Попытался удалить строку FROM, получил эту ошибку:

 Error : ERROR:  syntax error at or near "INNER"
LINE 4: INNER JOIN users ON queued_items.user_id = users.imported_id
         ^
  

Я также попытался добавить псевдоним к условиям FROM и JOIN

 UPDATE queued_items
SET queued_items.user_id = users.id,
    queued_items.item_id = items.id
FROM queued_items as qi
INNER JOIN users ON qi.user_id = users.imported_id
INNER JOIN items ON qi.item_id = items.imported_id
  

Получил эту ошибку:

 Error : ERROR:  column "queued_items" of relation "queued_items" does not exist
LINE 2: SET queued_items.user_id = users.id,
            ^
  

Есть идеи? (postgres 9)

PS Пытаюсь избежать этого подзапроса:

 UPDATE queued_items
SET user_id = (SELECT id FROM users WHERE queued_items.user_id = users.imported_id),
    item_id = (SELECT id FROM items WHERE queued_items.item_id = items.imported_id)
  

… потому что это безумно медленно

Комментарии:

1. Вы пробовали использовать псевдоним для queued_items в FROM предложении и условиях объединения?

2. Только что попробовал это. Я обновлю свой пост с результатами.

3. Удалите queued_items. из обеих частей SET предложения, ожидается, что левые части всегда будут ссылаться только на столбцы из таблицы, которую вы обновляете.

Ответ №1:

Попробуйте это:

 UPDATE queued_items
SET user_id = users.id,
    item_id = items.id
FROM users, items
WHERE queued_items.user_id = users.imported_id
  AND queued_items.item_id = items.imported_id
  

Да, старые школьные условия объединения.

Комментарии:

1. Ошибка: ОШИБКА: столбец «queued_items» отношения «queued_items» не существует

2. @jmccartie: Я думаю, что я исправил SQL. Пожалуйста, попробуйте мою обновленную версию.

3. Не могли бы вы, пожалуйста, объяснить, почему это работает?

4. @DavidWesby Вероятно, лучше всего начать с документов: postgresql.org/docs/current/sql-update.html

Ответ №2:

С сайта postgres

 UPDATE [ ONLY ] table [ [ AS ] alias ]
    SET { column = { expression | DEFAULT } |
          ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
  

*from_list*

Список табличных выражений, позволяющий столбцам из других таблиц отображаться в условии WHERE и выражениях update. Это похоже на список таблиц, которые могут быть указаны в предложении FROM инструкции SELECT. Обратите внимание, что целевая таблица не должна отображаться в from_list, если вы не собираетесь самосоединяться (в этом случае она должна отображаться с псевдонимом в from_list).

Комментарии:

1. Пример самостоятельного объединения?

Ответ №3:

 UPDATE queued_items
SET user_id = users.id,
    item_id = items.id
FROM queued_items as QI
INNER JOIN users ON QI.user_id = users.imported_id
INNER JOIN items ON QI.item_id = items.imported_id
  

Комментарии:

1. То, как я интерпретирую документацию по этому поводу: ‘queued_items’ сразу после ОБНОВЛЕНИЯ фактически обрабатывается как псевдоним, когда есть также предложение FROM . Технически этот запрос должен работать как UPDATE QI … ИЗ queued_items как QI… Итак, ошибка гласит: «Эй, этот псевдоним уже неявно принят». В принципе, если у нас есть только предложение where, то мне вообще не нужно полностью уточнять ссылки на поля таблицей, но как только я введу предложение From, нам нужно ввести псевдоним для таблицы, чтобы компилятор не запутался.

Ответ №4:

Мне пришлось поиграться с наименованием столбца / таблицы и в конечном итоге это сработало. Мне пришлось:

  • не указывайте имя таблицы в столбцах назначения SET
  • убедитесь, что я присвоил обновляемой таблице псевдоним

Ваш эквивалент был бы:

 UPDATE queued_items
SET user_id = users.id,
    item_id = items.id
FROM queued_items as alias_queued_items
INNER JOIN users ON alias_queued_items.user_id = users.imported_id
INNER JOIN items ON alias_queued_items.item_id = items.imported_id
  

вместо:

 UPDATE queued_items
SET queued_items.user_id = users.id,
    queued_items.item_id = items.id
FROM queued_items
INNER JOIN users ON queued_items.user_id = users.imported_id
INNER JOIN items ON queued_items.item_id = items.imported_id
  

Ответ №5:

Используйте инструкцию подзапроса и добавьте индексы к этим столбцам.

Ответ №6:

Не знаю, поможет ли это. В моем случае произошло то, что я eager loaded использовал данные, а также указал их как данные, к которым нужно присоединиться relations .

Ответ №7:

Вы должны иметь возможность изменить имя после UPDATE на псевдоним. Также вы можете использовать псевдонимные имена в предложении set. Это означает, что вы также можете задать их в своих JOIN предложениях.

 UPDATE qi 
SET qi.user_id = us.id,
    qi.item_id = itms.id
FROM queued_items qi
INNER JOIN users us ON qi.user_id = us.imported_id
INNER JOIN items itms ON qi.item_id = itms.imported_id
  

Комментарии:

1. Ошибка: ОШИБКА: отношение «qi» не существует

Ответ №8:

Вам не нужно предложение FROM . Удалите «ИЗ queued_items», и все готово.

Комментарии:

1. Удалено из строки —> Ошибка : ОШИБКА: синтаксическая ошибка в «ВНУТРЕННЕЙ» СТРОКЕ 4 или рядом с ней: ВНУТРЕННЕЕ объединение пользователей В queued_items.user_id = users.imported_id (я обновлю сообщение с этой ошибкой) ^