Sql 获得;最新;多个表上分组后的行
我最好先查询下面列出的内容,然后按Sql 获得;最新;多个表上分组后的行,sql,postgresql,greatest-n-per-group,postgresql-9.1,rails-postgresql,Sql,Postgresql,Greatest N Per Group,Postgresql 9.1,Rails Postgresql,我最好先查询下面列出的内容,然后按stories.id进行分组,但我得到以下错误: 错误:列“u.first\u name”必须出现在GROUP BY子句中或用于聚合函数第1行:选择“s”。*,“u”。“first\u name”,“u”。“last\u name”,“i”。“filen…” 第二个查询可以工作,但不按stories.id分组,并生成错误的结果。是否可以从多个表中选择,而不按所有表分组 表panels中还有一列updated\u(更新时间)。我想根据panels(更新时间)获取每
stories.id
进行分组,但我得到以下错误:
错误:列“u.first\u name”必须出现在GROUP BY子句中或用于聚合函数第1行:选择“s”。*,“u”。“first\u name”,“u”。“last\u name”,“i”。“filen…”
第二个查询可以工作,但不按stories.id
分组,并生成错误的结果。是否可以从多个表中选择,而不按所有表分组
表panels
中还有一列updated\u(更新时间)
。我想根据panels(更新时间)
获取每个故事的最新文件
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".*,
(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
它只会从“用户”
和“面板”中获得一条记录,并在“故事”
中的每条记录中加入“图像”
添加按
排序、额外的位置
或一些聚合,以从用户和面板中加入“图像”
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”
在澄清问题后更新:
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。
我使用,因为我不知道哪些列可能是NULL
。如果I.filename
和I.extension
都定义了notnull
,您可以简化
根据
项目更新的附加的
订单的效果是,每个故事都会选择“最新的”文件。查询技术在这个相关问题下有完整的解释:
第二次查询的结果如何出错?@Igor Romanchenko没有按故事分组。我们的问题没有定论。如果你想按story.id
分组,你必须定义从多行中选择什么。使用如此多的子选择是否有性能差异?@stefan大多数时候postgres会优化查询,所以不会有太大的性能差异。@stefan:通常,相关子查询是一种反性能模式。如果可以,请避免它们。但是正如@Igor所提到的,Postgres可以在有利的条件下优化查询计划。使用测试并比较您的查询,以获得明确的答案。运行多次以排除缓存影响。这查询工作正常,除了我得到一个文件列表97799.jpg,5234.jpg
我真正想要的是最后一个文件面板有一个顺序并按列创建,我只需要最新的。@stefan:你需要编辑你的问题并将所有信息放在那里。这是一个公共论坛,一个问题应该能描绘出一幅完整的画面。评论s根本不够好。请在问题下方使用edit
。
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;