首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在具有postgres的rails中使用不同in的顺序

问在具有postgres的rails中使用不同in的顺序
EN

Stack Overflow用户
提问于 2015-07-25 07:38:00
回答 2查看 773关注 0票数 1

下面的代码将两个表、微博和活动与micropost_id列连接起来,然后根据具有不同micropost id的活动表的created_at进行排序。

代码语言:javascript
复制
 Micropost.joins("INNER JOIN activities ON 
 (activities.micropost_id = microposts.id)").
 where('activities.user_id= ?',id).order('activities.created_at DESC').
 select("DISTINCT (microposts.id), *")

在我的开发环境中,应该返回完整的微站columns.This。

代码语言:javascript
复制
(PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

如果我在SELECT DISTINCT中添加activities.created_at,我将得到重复的微柱ids,因为有不同的activities.created_at列。我已经做了很多搜索才到达这里。但问题始终存在,因为这种postgres条件,以避免随机选择。

我想选择基于顺序的activities.created_at与不同的微柱_id。

请帮忙..。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-26 04:20:31

首先,我们需要快速介绍SELECT DISTINCT实际上正在做的事情。它看起来只是一个很好的关键字,以确保您只返回不同的值,这不应该改变任何东西,对吗?但正如你所发现的,在幕后,SELECT DISTINCT实际上更像是一个GROUP BY。如果你想选择某物的不同值,你只能按照你选择的相同的值来排序结果集--否则,Postgres不知道该怎么做。

要解释歧义的来源,请考虑为您的activities提供这组简单的数据。

代码语言:javascript
复制
CREATE TABLE activities (
  id INTEGER PRIMARY KEY,
  created_at TIMESTAMP WITH TIME ZONE,
  micropost_id INTEGER REFERENCES microposts(id)
);
INSERT INTO activities (id, created_at, micropost_id)
VALUES (1, current_timestamp,                      1),
       (2, current_timestamp - interval '3 hours', 1),
       (3, current_timestamp - interval '2 hours', 2)

你在你的问题中说,你想要“不同的micropost_id”“基于activities.created_at的顺序”。通过降序created_at (1, 3, 2)来排序这些活动很容易,但是1和2的micropost_id都是1。

如果您能够回答上面的问题,您需要使用您的逻辑这样做,并将其移到您的查询中。比方说,我认为这是很有可能的,你希望这是一个微型帖子的列表,这是最近采取行动的。在这种情况下,您希望按它们最近的活动的降序排序。Postgres可以通过多种方式为你做到这一点,但在我看来,最简单的方法是:

代码语言:javascript
复制
SELECT micropost_id
FROM activities
JOIN microposts ON activities.micropost_id = microposts.id
GROUP BY micropost_id
ORDER BY MAX(activities.created_at) DESC

请注意,我已经放弃了SELECT DISTINCT位,转而使用GROUP BY,因为Postgres处理它们要好得多。MAX(activities.created_at)位告诉Postgres,对于具有相同micropost_id的每一组活动,只对最近的一组进行排序。

您可以将上述内容转换为如下所示的Rails:

代码语言:javascript
复制
Micropost.select('microposts.*')
  .joins("JOIN activities ON activities.micropost_id = microposts.id")
  .where('activities.user_id' => id)
  .group('microposts.id')
  .order('MAX(activities.created_at) DESC')

希望这能有所帮助!如果您想更多地了解查询是如何工作的,可以使用这个sqlFiddle。

票数 4
EN

Stack Overflow用户

发布于 2015-07-25 07:56:35

试试下面的代码

代码语言:javascript
复制
Micropost.select('microposts.*, activities.created_at')
.joins("INNER JOIN activities ON (activities.micropost_id = microposts.id)")
.where('activities.user_id= ?',id)
.order('activities.created_at DESC')
.uniq
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31624159

复制
相关文章

相似问题

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