首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按不同的列选择Distinct while

按不同的列选择Distinct while
EN

Stack Overflow用户
提问于 2013-11-16 05:51:21
回答 2查看 4.2K关注 0票数 3

我来自MySQL背景,那里的团队工作方式与Postgres非常不同。在Postgres (显然是任何基于标准的SQL数据库)中,您必须按所有选定的列进行分组,而在MySQL中,您可以手动选择要分组的列。

我读到,您可以通过DISTINCT ON获得同等的效果,而且大多数情况下都是这样的。问题在于,您必须对所有不同的列进行ORDER BY,并且这种排序必须是最左边的排序。这是一个问题,当我想主要通过另一栏订购。

现在,我的查询如下:

代码语言:javascript
复制
SELECT
  DISTINCT ON (eventable_id, eventable_type)
           events.eventable_id, events.eventable_type, events.*
  FROM events
  WHERE <query>
  ORDER BY eventable_id, eventable_type, events.created_at DESC

我想换一下订单,如下所示:

代码语言:javascript
复制
  ORDER BY events.created_at, eventable_id, eventable_type DESC

有什么建议能让这件事成功吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-16 07:20:00

由于选择了events.*,所以不应该冗余地将eventable_ideventable_type添加到输出列中。会导致重复的列名。您知道,不必在目标列表中的DISTINCT ON子句中包括列,对吗?

而且,使用eventable_type DESC的速度可能会更快,因为在最后的排序顺序中有了这一点。这也是允许的。

代码语言:javascript
复制
SELECT DISTINCT ON (eventable_id, eventable_type)
       *
FROM   events
WHERE  <condition>
ORDER  BY eventable_id, eventable_type DESC, created_at DESC

@Denis已经涵盖了其余部分:使其成为一个子查询,并按您在外部查询中喜欢的顺序进行排序。

alternative将是一个带有GROUP BYmax()的子选择,但如果每个组的最新created_at并不是唯一的,则每个组会产生多个列。(可能或不适宜。)而且,它可能仍然比DISTINCT ON慢一个额外的ORDER BY步骤。用EXPLAIN ANALYZE进行测试。

代码语言:javascript
复制
SELECT e.*
FROM   events e
JOIN  (
   SELECT eventable_id, eventable_type, max(created_at) AS created_at
   FROM   events
   WHERE  <condition>
   GROUP   BY 1, 2 DESC
   ) sub USING (eventable_id, eventable_type, created_at) -- maybe not unique
WHERE  <repeat condition if dupes may be eliminated>
ORDER  BY e.created_at, e.eventable_id, e.eventable_type DESC
票数 4
EN

Stack Overflow用户

发布于 2013-11-16 06:31:01

如果Postgres抱怨,请使用子选择:

代码语言:javascript
复制
select * from ( ... ) q order by ...

(如果是这样的话,我会把它当作查询计划会很糟糕的暗示。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20015260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档