为每个用户选择MAX行(最新事件)(有条件的两个表联接)

时间:2018-11-24 10:03:50

标签: sql postgresql join select greatest-n-per-group

我是Postgres的新手,并且对看似简单的任务有疑问。.我已经阅读了许多示例,并且其中许多示例仅在一个表中出现,所以我在这里寻求帮助!

我有一个用户表和一个事件表。

用户由user_id,名称,user_type组成

事件由事件ID,用户ID,事件名称,事件类型,事件日期组成

我想获取每个用户的最新事件,其中user_type =已满,event_type =已付费

我尝试了以下操作,但Postgres告诉我“错误:列“ e.event_name”必须出现在GROUP BY子句中或在聚合函数中使用“

select 
  u.user_id, 
  u.user_type, 
  max(e.event_id), 
  e.event_name 
from 
  users u 
  join events e on u.user_id = e.user_id 
where 
  u.user_type = 'full' 
  and e.event_type = 'paid' 
group by 
  u.user_id

注意:一些解决方案提到DISTINCT ON,但是我正在使用的系统认为这不是有效的SQL。

2 个答案:

答案 0 :(得分:1)

如您所见,您不能像这样混合使用row和aggerate函数。 一种常见的方法是使用row_number窗口函数按事件的日期(每个用户)对事件进行排序,然后仅采用第一个事件:

SELECT *
FROM   (SELECT *,
               ROW_NUMBER() OVER (PARTITION BY u.user_id ORDER BY event_date DESC) AS rn
        FROM   users u
        JOIN   events e ON u.user_id = e.user_id
        WHERE  user_type = 'full' AND
               event_type = 'paid') t
WHERE  rn = 1

答案 1 :(得分:0)

Postgres中最有效的方法通常是使用distinct on

select distinct on (u.user_id) u.user_id, u.user_type, 
       e.event_id, e.event_name 
from users u join
     events e
     on u.user_id = e.user_id 
where u.user_type = 'full' and
      e.event_type = 'paid' 
order by u.user_id, e.event_date desc;