PostgreSQL:式として使用されるサブクエリによって返される複数の行

Aug 21 2020

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

サブクエリに問題があると思ったので、個別に使用して、1行しか取得しませんでした。そのためLIMIT 1、サブクエリ内で使用し、期待した結果が得られましたが、クエリでは意味がありません。誰かがこの振る舞いを説明できますか?また、タイプを使用しているため、main.usersテーブルにuser_id重複は含まれていませんSERIAL

  • PostgreSQL 12.4

回答

1 AkhileshMishra Aug 21 2020 at 17:45

本当の犯人はあなたのコードのこの行です

(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
1 LaurenzAlbe Aug 21 2020 at 18:39

問題があるということ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;
FranckT Aug 25 2020 at 17:32

最初に空白の値を入力できます

       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;

テストしませんでしたが、動作するはずです