#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:
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 (я обновлю сообщение с этой ошибкой) ^