DISTINCT ON查询使用/ ORDER BY列的最大值

时间:2015-04-01 16:29:20

标签: mysql sql ruby-on-rails postgresql activerecord

我的任务是将一个Rails应用程序从MySQL转换为Postgres asap并遇到一个小问题。
活动记录查询:

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. 我不知道如何通过max function
  3. 的结果订购
  4. 我甚至可以使用这样的max函数吗?
  5. 此查询的高级目标是返回用户的6个最新配置文件视图。任何有关如何修复此ActiveRecord查询(或它产生的SQL)的指针都将非常感激。

1 个答案:

答案 0 :(得分: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必须与{{1}具有相同的前导列}}

您需要外部查询才能获得最新的6位访问者 考虑一系列事件:

为什么DISTINCT ON?可以肯定的是,您没有提供表格定义。