【问题标题】:Strange postgres SELECT ordering issue奇怪的 postgres SELECT 排序问题
【发布时间】:2012-01-20 17:11:14
【问题描述】:

我有这个 postgres sql 查询:

select * from stats where athlete_id = 5

正如你想象的那样,这将返回每个 ID 为 5 的运动员的所有统计数据

到目前为止一切正常。

但是我刚刚注意到,对于大于 110 的运动员 ID,它以相反的顺序返回统计数据行。

因此,对于运动员 ID = 110,'id' 列会像这样出现,这是我习惯的:

2325
2401
2482
2537
2592
2647
...

等等。每个统计表行按 id 排序。

那么如果你选择 111,就会出现这样的结果:

5652
5610
5569
5528
5487
5437
5387
5336
...

这怎么可能?这都是在 pgadmin 界面内进行的查询。没有额外的 where 子句,只有我说过的那个,即 WHERE player_id = 111

什么?我一直在进行各种代码更改,但是在 pgaadmin /pgsql 中到底是什么导致了这种情况?

110 和 111 之间发生了什么?在 Rails 中进行了大量的重构和代码更改,但没有实际的直接 SQL 操作。是的,我意识到答案可能在那里,但我不知道如何看,因为这不在 rails 应用程序中 - 这是通过 pgadmin 的纯 SQL,所以必须在 postgres 中完成一些事情 - 我需要了解什么可能是这样,或者我无法调试。

有什么想法吗?在 Rails 中,诸如:

Athlete.stats.last.score 返回“第一”行而不是“最后”行,完全搞砸了应用程序,但仅适用于 id 大于 110 的运动员!

完全糊涂了!

【问题讨论】:

  • 行在数据库中不是按特定顺序保存的,如果你想让行按列排序,请使用按列排序,

标签: sql ruby-on-rails postgresql select


【解决方案1】:

如果您不指定 ORDER BY 子句,则 no 保证行将按什么顺序返回。它们可以是升序、降序、没有明显的逻辑,甚至可能在您每次查询时使用不同的顺序(尽管这在实践中不太可能发生)。

你得到的具体顺序是由于查询计划中步骤的实现细节。当您更改参数时,它可能会导致 PostgreSQL 更喜欢一个查询计划而不是另一个。例如,它可能决定对一个查询使用表扫描,而对另一个查询使用索引。在您的具体情况下很难确切知道原因,但查看 EXPLAIN 的结果可能会给出一些提示。

要修复您的查询以按您期望的顺序返回行,请添加 ORDER BY 子句:

SELECT *
FROM stats
WHERE athlete_id = 5
ORDER BY id

【讨论】:

  • 可以写 ORDER BY id ASC 或 ORDER BY id DESC 来指定顺序(A-Z 或 Z-A)
  • 我明白这一切。但有些事情发生了变化。而且,如果 ruby​​/rails 没有实现 order by 以使用 '.find' 方法......它到底在做什么?我现在正试图弄清楚这一点。看起来很奇怪,rails 会依赖于上面答案中描述的任何查询计划。
  • @Dave:如果你说的是Stat.where('athlete_id = ?', 5)(或类似的),那么 Rails 不会包含 ORDER BY 子句,因为你没有要求,如果你想要一个 ORDER BY 那么你需要添加一个.order('whatever ordering you want') 电话。既然你没有要求,Rails 为什么还要麻烦排序呢?
  • Hi mu 太短 --> 正确。我在做:
  • 抱歉,按回车键并提交评论。我在做:lastStat = self.videostats.last ...但是查看日志并没有添加 order by 子句。我已将其更改为 lastStat = self.videostats.find_last 并且确实添加了 order_by 并且一切正常。它没有解释发生了什么改变了排序[我知道排序可以是任意的,但它确实改变了]但一个很大的难题是 110 是从 heroku db 转储下载的最后一个条目,而 111 是一个新条目.所以它对我来说仍然是一个谜,但到处都有线索!
【解决方案2】:

除非您在查询中指定 ORDER BY 子句,否则您不能假设/期望 SQL 会以任何特定顺序将数据返回给您。

【讨论】:

    猜你喜欢
    • 2016-08-07
    • 2011-02-02
    • 2010-11-28
    • 2010-10-28
    • 1970-01-01
    • 2011-07-31
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多