使用Postgres 9.4
我有一个与用户表相关的帖子表。我查询了两个用户和3个最近的帖子。
SELECT
"users"."id" AS "id",
"posts"."id" AS "posts__id",
"posts"."created_at" AS "posts__created_at"
FROM (
SELECT * FROM accounts
WHERE TRUE
ORDER BY "id" ASC
LIMIT 2
) AS "users"
LEFT JOIN LATERAL (
SELECT * FROM posts
WHERE "users".id = posts.author_id
ORDER BY "created_at" DESC, "id" DESC
LIMIT 3
) AS "posts" ON "users".id = "posts".author_id
在Mac上,订单符合预期。
"2016-04-17 18:49:15.942"
"2016-04-15 03:29:31.212"
"2016-04-13 15:07:15.119"
我在created_at
上降序,这是timestamptz
。但是,当我的travis构建(Ubuntu)运行时,顺序是稳定的,但既不上升也不下降......
"2016-04-15 03:29:31.212"
"2016-04-13 15:07:15.119"
"2016-04-17 18:49:15.942"
我让用户使用相同的LC_COLLATE = en_US.UTF-8
创建数据库而没有运气。为什么在travis上没有订购?
答案 0 :(得分:1)
您可能还需要订购外部查询,因为2个内部查询之间的连接,即使在订购时也不会得到保证。
SELECT
"users"."id" AS "id",
"posts"."id" AS "posts__id",
"posts"."created_at" AS "posts__created_at"
FROM (
SELECT * FROM accounts
WHERE TRUE
ORDER BY "id" ASC
LIMIT 2
) AS "users"
LEFT JOIN LATERAL (
SELECT * FROM posts
WHERE "users".id = posts.author_id
ORDER BY "created_at" DESC, "id" DESC
LIMIT 3
) AS "posts" ON "users".id = "posts".author_id
order by "posts"."created_at" DESC
答案 1 :(得分:1)
因为实际的排序顺序取决于第一个表格中id
的顺序和created_at
&的顺序。第二个之前中的id
加入他们。这意味着在从连接表计算选定值时,第一个表的顺序会产生意外结果。
要修复排序顺序,您还应该按相关列对最终结果集进行排序。
答案 2 :(得分:1)
要解决此问题,只需在上面的现有语句下添加order by语句。 即。
SELECT
"users"."id" AS "id",
"posts"."id" AS "posts__id",
"posts"."created_at" AS "posts__created_at"
FROM (
SELECT * FROM accounts
WHERE TRUE
ORDER BY "id" ASC
LIMIT 2
) AS "users"
LEFT JOIN LATERAL (
SELECT * FROM posts
WHERE "users".id = posts.author_id
ORDER BY "created_at" DESC, "id" DESC
LIMIT 3
) AS "posts" ON "users".id = "posts".author_id
order by posts.created_at desc
如果没有order by语句,就无法保证postgres(以及许多其他dbms)的输出顺序。
虽然您确实有按语句排序,但它们在子查询中,您需要在外部查询上按顺序排序。