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...

第二個查詢作品但不會按stories.id分組,並生成錯誤的結果。是否可以從多個表中進行選擇而不是全部進行分組?

panels也有一列updated_at。我想根據panels.updated_at得到每個故事最新的file

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 
+0

第二個查詢的結果是怎麼錯了? –

+0

@Igor Romanchenko它不是由故事編號組編號 – Stefan

+0

您的問題沒有定論。如果你想通過'story.id'進行分組,你可以*從多行中定義要做什麼。 –

回答

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; 

Grouping by primary key需要PostgreSQL 9.1。
我使用concat_ws(),因爲我不知道哪些列可能是NULL。如果i.filenamei.extension都定義爲NOT NULL,則可以簡化。

額外的ORDER BY項目p.updated_at DESC的影響是每個故事將挑選「最新」file。查詢技術在這個相關的問題下全部解釋:
Select first row in each GROUP BY group?

+0

這個查詢的工作原理除了我得到一個文件列表'97799.jpg,5234.jpg'我真正在尋找的是最後一個文件面板有一個訂單,並按列創建,我只需要最新的。 – Stefan

+1

@stefan:你需要編輯你的問題,並把所有的信息。這是一個公共論壇,一個問題應該畫一幅完整的圖畫。評論根本不夠好。在你的問題下使用'edit'。 –

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 

這將只留下一排,每不同"s"."id"

+0

使用如此多的子選擇會有性能差異嗎? – Stefan

+0

@stefan大多數時候postgres都會優化查詢,所以不會有太大的性能差異。 –

+1

@stefan:通常,相關子查詢是一種反性能模式。如果可以的話,避免它們。但是@Igor提到,Postgres可以在有利條件下優化查詢計劃。使用['EXPLAIN ANALYZE'](http://www.postgresql.org/docs/current/interactive/sql-explain.html)測試您的查詢並進行比較以獲得確定的答案。多次運行以排除緩存效果。 –

相關問題