2015-04-01 48 views
1

我一直负责将Rails应用程序从MySQL转换为Postgres,并遇到小问题。
活动记录查询:DISTINCT ON查询w/ORDER BY列的最大值

current_user.profile_visits.limit(6).order("created_at DESC").where("created_at > ? AND visitor_id <> ?", 2.months.ago, current_user.id).distinct

主要生产的SQL:

SELECT visitor_id, MAX(created_at) as created_at, distinct on (visitor_id) * 
FROM "profile_visits" 
WHERE "profile_visits"."social_user_id" = 21 
AND (created_at > '2015-02-01 17:17:01.826897' AND visitor_id <> 21) 
ORDER BY created_at DESC, id DESC 
LIMIT 6 

使用MySQL时,我非常有信心,但我诚实新的Postgres。我认为这个查询失败的原因有很多。

  1. 我认为需要首先区分。
  2. 我不知道如何按最大功能的结果排序
  3. 我可以使用像这样的最大功能吗?

此查询的高级别目标是返回用户的最近6个配置文件视图。任何指针如何解决这个ActiveRecord查询(或它的结果SQL)将不胜感激。

+0

有问题的查询将不会使用MySQL。 'distinct on'是一个Postgres构造,所以我假设整个事物都是Postgres兼容的。但是,使用'max()'是非常可疑的。 – 2015-04-01 16:38:51

+0

一如既往,您的Postgres版本和表格定义应该在问题中。此外,查询应该做什么的描述可能不完整。 – 2015-04-02 20:44:41

回答

0

此查询的高层次目标是返回6最近 个人资料被访问用户的

这会很简单。你并不需要为这个max()也不DISTINCT

SELECT * 
FROM profile_visits 
WHERE social_user_id = 21 
AND created_at > (now() - interval '2 months') 
AND visitor_id <> 21 -- ?? 
ORDER BY created_at DESC NULLS LAST, id DESC NULLS LAST 
LIMIT 6; 

我怀疑你的问题是不完整的。如果你想:
与页面
他们的最新访问了6个最新访客,那么你需要一个子查询。你不能在一个查询级别得到这个排序顺序,也没有用DISTINCT ON,也不能与窗口函数:

SELECT * 
FROM (
    SELECT DISTINCT ON (visitor_id) * 
    FROM profile_visits 
    WHERE social_user_id = 21 
    AND created_at > (now() - interval '2 months') 
    AND visitor_id <> 21 -- ?? 
    ORDER BY visitor_id, created_at DESC NULLS LAST, id DESC NULLS LAST 
    ) sub 
ORDER BY created_at DESC NULLS LAST, id DESC NULLS LAST 
LIMIT 6; 

子查询sub获取每个用户的最新访问(但年龄不超过两个月,没有一定访客21ORDER BY必须具有相同的前导列作为DISTINCT ON

您需要外部查询,以获得最新的6名参观者然后
考虑事件的顺序:。

为什么NULLS LAST?可以肯定的是,你没有提供表格定义。