Postgres在时间戳上排序适用于mac但不适用于linux

时间:2016-10-20 20:45:56

标签: linux postgresql travis-ci

使用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上没有订购?

3 个答案:

答案 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)的输出顺序。

虽然您确实有按语句排序,但它们在子查询中,您需要在外部查询上按顺序排序。