1

最初に以下にリストされたクエリを実行しstories.id、 でグループ化することをお勧めしますが、次のエラーが発生します。

ERROR: column "u.first_name" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT "s".*, "u"."first_name", "u"."last_name", ("i"."filen...

2 番目のクエリは機能しますが、グループ化は行われずstories.id、間違った結果が生成されます。複数のテーブルから選択して、それらすべてでグループ化することはできますか?

panelsには列もありますupdated_atfileに従って、ストーリーごとに最新のものを入手したいと思いpanels.updated_atます。

   SELECT 
        "s".*, 
        "u"."first_name", 
        "u"."last_name", 
        ("i"."filename" || '.' || "i"."extension") AS "file" 
    FROM 
        "stories" "s" 
    LEFT JOIN "panels" "p" ON("p"."story_id" = "s"."id") 
    LEFT JOIN "users" "u" ON("s"."user_id" = "u"."uid")
    LEFT JOIN "images" "i" ON ("p"."image_id" = "i"."id") 
    WHERE 
        "s"."complete" = false AND 
        "s"."created_by" = 205700489 
    GROUP BY 
        "s"."id", 
    ORDER BY 
        "s"."created_at" DESC

   SELECT 
        "s".*, 
        "u"."first_name", 
        "u"."last_name", 
        ("i"."filename" || '.' || "i"."extension") AS "file" 
    FROM 
        "stories" "s" 
    LEFT JOIN "panels" "p" ON("p"."story_id" = "s"."id") 
    LEFT JOIN "users" "u" ON("s"."user_id" = "u"."uid")
    LEFT JOIN "images" "i" ON ("p"."image_id" = "i"."id") 
    WHERE 
        "s"."complete" = false AND 
        "s"."created_by" = 205700489 
    GROUP BY 
        "s"."id", 
        "u"."first_name", 
        "u"."last_name", "i"."filename", 
        "i"."extension" 
    ORDER BY 
        "s"."created_at" DESC
4

2 に答える 2

2

質問の明確化後に更新:

SELECT DISTINCT ON (s.created_at, s.id)
       s.*
      ,u.first_name
      ,u.last_name
      ,concat_ws('.', i.filename, i.extension) AS file
FROM   stories s 
LEFT   JOIN users  u ON u.uid = s.user_id
LEFT   JOIN panels p ON p.story_id = s.id
LEFT   JOIN images i ON i.id = p.image_id
WHERE  s.complete = false
AND    s.created_by = 205700489 
ORDER  BY s.created_at DESC, s.id, p.updated_at DESC;

主キーによるグループ化には、 PostgreSQL 9.1 が必要です。どの列が であるかわからないため、
を使用します。との両方が定義されている場合は、簡略化できます。concat_ws()NULLi.filenamei.extensionNOT NULL

追加ORDER BYアイテムの効果は、ストーリーごとにp.updated_at DESC「最新」が選択されることです。fileクエリ手法は、次の関連する質問で完全に説明されています:
各 GROUP BY グループで最初の行を選択しますか?

于 2012-11-29T15:47:37.017 に答える
0

次のように書くことができます:

   SELECT 
        "s".*, 
        (SELECT "u"."first_name" 
         FROM "users" "u"
         WHERE "s"."user_id" = "u"."uid"
         LIMIT 1) , 
        (SELECT "u"."last_name" 
         FROM "users" "u"
         WHERE "s"."user_id" = "u"."uid"
         LIMIT 1), 
        (SELECT "i"."filename" || '.' || "i"."extension"
         FROM "panels" "p" 
         JOIN "images" "i" ON ("p"."image_id" = "i"."id")
         WHERE "p"."story_id" = "s"."id" 
         LIMIT 1) AS "file" 
    FROM 
        "stories" "s" 
    WHERE 
        "s"."complete" = false AND 
        "s"."created_by" = 205700489 
    ORDER BY 
        "s"."created_at" DESC

"users"から、"panels" JOIN "images"レコードごとに1 つのレコードのみを取得し"stories"ます。

ORDER BY、余分なWHERE、またはいくつかの集計を追加して、必要なものを取得し"users""panels" JOIN "images"

UPD また、次のようなものを使用できます。

SELECT *
FROM (
SELECT DISTINCT ON ("s"."id") 
    "s".*, 
    "u"."first_name", 
    "u"."last_name", 
    ("i"."filename" || '.' || "i"."extension") AS "file" 
FROM 
    "stories" "s" 
LEFT JOIN "panels" "p" ON("p"."story_id" = "s"."id") 
LEFT JOIN "users" "u" ON("s"."user_id" = "u"."uid")
LEFT JOIN "images" "i" ON ("p"."image_id" = "i"."id") 
WHERE 
    "s"."complete" = false AND 
    "s"."created_by" = 205700489 
ORDER BY 
    "s"."id"
) t ORDER BY "t"."created_at" DESC

個別ごとに1行のみを残します"s"."id"

于 2012-11-29T13:58:31.450 に答える