无法让DISTINCT + GROUP与Postgres一起使用两个值

时间:2012-12-24 02:32:19

标签: sql postgresql group-by distinct

尝试获取最新活动,使用不同的user_id,按“最新”(订单“id desc”或“created_at desc”)排序:

SELECT DISTINCT ON (id, user_id) id,user_id 
FROM "activities" 
GROUP BY id,user_id 
ORDER BY id desc LIMIT 10

但是使用以下user_ids返回10个结果:

2863, 2863, 2863, 2863, 2863, 2863, 2863, 2863, 2863, 2615

显然,这并不明显。我如何得到它,以便它有一个独特的(分组的)user_id?

编辑:也许我解释得很糟糕,我道歉。真的很简单,我想要来自唯一user_id的最新活动。根据最新情况,我更喜欢create_at,但是id也适用。我只想要每个用户一个,没有重复。

再次编辑:意识到第一句确实是在抛弃回答者。很抱歉让所有人都离开那里,我想要的非常简单:/。

4 个答案:

答案 0 :(得分:1)

试试这个:

select user_id, array_agg(id) as ids
from activities
group by user_id
having count(*) > 1;

array_agg()函数以逗号分隔的列表的形式返回组的所有值。

编辑:

从评论中可能只是想要这个:

select distinct user_id
from activities;

或者可能是这样,它只显示那些具有重复项的用户ID:

select user_id
from activities
group by user_id
having count(*) > 1;

答案 1 :(得分:1)

我不确定你想要什么,但试试这个:

SELECT id, user_id
FROM (
   SELECT id
        , user_id
        , ROW_NUMBER () OVER (PARTITION BY id
                              ORDER BY user_id DESC) as rn
   FROM "activities"
   ) as xx
WHERE rn = 1
ORDER BY id desc 
LIMIT 10

ROW_NUMBER OLAP函数将在id

的值内分配计数器

答案 2 :(得分:1)

RE:我想要来自唯一user_id的最新活动

SELECT DISTINCT ON (user_id) user_id, created_at
FROM "activities" 
ORDER BY user_id, created_at desc

RE:那我怎么得到身份证?我还需要ids

重复使用上面的查询:

with latest_activities as
(
  SELECT DISTINCT ON (user_id) user_id, created_at
  FROM "activities" 
  ORDER BY user_id, created_at desc
)
select l.user_id, l.created_at, array_agg(a.id) as ids
from latest_activities l
join activities a using(user_id)
group by l.user_id, l.created_at

答案 3 :(得分:1)

如果你有一些最新的关系活动,例如

user_id created_at      id
john    july 4, 2010    1
john    july 4, 2010    2
john    july 12, 2010   3        -- ties with id# 4
john    july 12, 2010   4        -- ties with id# 3
john    july 5, 2010    5
paul    july 13, 2010   6
paul    july 12, 2010   7

使用dense_rank:

with latest_activities as
(
    SELECT user_id, created_at, id,
        dense_rank() 
        over(partition by user_id order by created_at desc) as the_ranking
    FROM activities     
)
select * 
from latest_activities
where the_ranking = 1
order by user_id, id;

上面的查询将显示:

user_id created_at      id 
john    july 12, 2010   3
john    july 12, 2010   4
paul    july 13, 2010   6

如果您希望每个用户的多个ID仅出现在一行上,请使用 group_concat array_agg,然后它将显示:

user_id created_at      ids
john    july 12, 2010   3, 4
paul    july 13, 2010   6

ARRAY_AGG:

with latest_activities as
(
    SELECT user_id, created_at, id,
        dense_rank() 
        over(partition by user_id order by created_at desc) as the_ranking
    FROM activities     
)
select user_id, created_at, array_agg(id order by id) as ids
from latest_activities
where the_ranking = 1
group by user_id, created_at

请注意,上面的查询也在处理没有关系的数据

实时测试:http://www.sqlfiddle.com/#!12/c48ec/8