#sql #postgresql #sql-insert #postgresql-12
#sql #postgresql #sql-вставка #postgresql-12
Вопрос:
У меня есть main.comments
таблица, в которой я храню комментарии пользователей. Я пытаюсь добавить комментарий к базе данных и получить некоторые данные в качестве возврата. Вот мой запрос
INSERT INTO main.comments (text, post_id, user_id)
VALUES('sample', 11, 1)
RETURNING
comment_id,
text,
post_id,
(SELECT username FROM main.users WHERE main.users.user_id = user_id) AS username,
created_at,
updated_at
Итак, я ожидал добавить комментарий и получить нужные мне данные, но этого не произошло, вместо этого я получил эту ошибку
ОШИБКА: более одной строки, возвращаемой подзапросом, используемым в качестве выражения Состояние SQL: 21000
Я думал, что у меня проблема с подзапросом, поэтому я использовал его по отдельности и получил взамен только одну строку. Итак, я использовал LIMIT 1
в рамках подзапроса и получил ожидаемый результат, но это не имеет смысла в моем запросе. Может кто-нибудь, пожалуйста, объяснить такое поведение? А также моя main.users
таблица не содержит никаких user_id
дубликатов, поскольку я использую SERIAL
тип.
- PostgreSQL 12.4
Комментарии:
1.
WHERE
Условие в подзапросе будетTRUE
для всех строк, гдеuser_id IS NOT NULL
.2. @LaurenzAlbe Спасибо за ответ, есть ли какие-либо решения для этого или я должен просто придерживаться обходных путей, таких как LIMIT?
3. обходной путь @aingthed Limit не сработает. это даст неправильное имя.
Ответ №1:
Настоящим виновником является эта строка в вашем коде
(SELECT username FROM main.users WHERE main.users.user_id = user_id)
Попробуйте сделать это следующим образом:
INSERT INTO comments (text, post_id, user_id)
VALUES('sample', 11, 1)
RETURNING
comment_id,
text,
post_id,
(SELECT username FROM users t1 WHERE t1.user_id = comments.user_id) AS username,
created_at,
updated_at
I have removed the schema name for clarity
Ответ №2:
Проблема в том, что user_id
в вашем подзапросе ссылается не на вновь вставленную строку в main.comments
, а на main.users
, поэтому выполняется условие TRUE
и возвращаются все строки из users
.
Я бы использовал CTE это так:
WITH ins AS (
INSERT INTO main.comments (text, post_id, user_id)
VALUES('sample', 11, 1)
RETURNING
comment_id,
text,
post_id,
user_id,
created_at,
updated_at
)
SELECT ins.comment_id,
ins.text,
ins.post_id,
u.username,
ins.created_at,
ins.updated_at
FROM ins
JOIN main.users AS u ON ins.user_id = u.user_id;
Ответ №3:
вы могли бы сначала ввести пустые значения
INSERT INTO main.comments (text, post_id, user_id)
VALUES('sample', 11, 1)
RETURNING
comment_id,
text,
post_id,
NULL AS username,
created_at,
updated_at;
затем обновите свою таблицу
UPDATE main.comment
SET username = (SELECT username )
FROM main.users
WHERE main.users.user_id = main.comment.user_id;
не тестировался, но должен работать