Sql 无法让DISTINCT+组使用具有两个值的Postgres

Sql 无法让DISTINCT+组使用具有两个值的Postgres,sql,postgresql,group-by,distinct,Sql,Postgresql,Group By,Distinct,尝试获取具有不同用户id的最新活动,这些活动由最新的order 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 但这将返回10个结果,其中包含以下用户ID: 2863, 2863, 2863, 2863, 2863, 2863, 2863, 2863, 2863, 26

尝试获取具有不同用户id的最新活动,这些活动由最新的order 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
但这将返回10个结果,其中包含以下用户ID:

2863, 2863, 2863, 2863, 2863, 2863, 2863, 2863, 2863, 2615
很明显,这些都不明显。我如何获得它,使其具有一个独特的分组用户id

编辑:也许我解释得不好,我道歉。简单地说,我想要唯一用户id的最新活动。到目前为止,我更喜欢由created_at创建,但由id也可以。我只希望每个用户有一个,没有重复

再次编辑:意识到第一句话真的是把回答者甩了。很抱歉把所有人都抛在一边,我想要的其实很简单:/。

试试这个:

select user_id, array_agg(id) as ids
from activities
group by user_id
having count(*) > 1;
该函数以逗号分隔的列表形式返回组的所有值

编辑: 从评论中可以看出,您可能只是想要:

select distinct user_id
from activities;
或者,这可能只显示那些具有重复项的用户ID:

select user_id
from activities
group by user_id
having count(*) > 1;
试试这个:

select user_id, array_agg(id) as ids
from activities
group by user_id
having count(*) > 1;
该函数以逗号分隔的列表形式返回组的所有值

编辑: 从评论中可以看出,您可能只是想要:

select distinct user_id
from activities;
或者,这可能只显示那些具有重复项的用户ID:

select user_id
from activities
group by user_id
having count(*) > 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

行数OLAP函数将在id值内分配一个计数器。

我不确定您想要什么,但请尝试以下方法:

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

行数OLAP函数将在id值内分配一个计数器。

RE:我想要唯一用户id的最新活动

SELECT DISTINCT ON (user_id) user_id, created_at
FROM "activities" 
ORDER BY user_id, created_at desc
RE:那我怎么才能拿到身份证呢?我还需要身份证

重复使用上面的查询:

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

回复:我想要唯一用户的最新活动

SELECT DISTINCT ON (user_id) user_id, created_at
FROM "activities" 
ORDER BY user_id, created_at desc
RE:那我怎么才能拿到身份证呢?我还需要身份证

重复使用上面的查询:

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

如果您有一些与领带有关的最新活动,例如

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
使用密集排列:

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
数组_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
请注意,上面的查询也适用于没有关联的数据


现场测试:

如果您有一些与领带有关的最新活动,例如:

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
使用密集排列:

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
数组_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
请注意,上面的查询也适用于没有关联的数据


Live test:

不需要聚合,我只是把它放在那里,因为我要返回的是用户id,而我想得到唯一的。这只是返回用户id,我只需要从唯一的用户id中选择id。不需要聚合,我只是把它放在那里,因为我要返回的是用户id,我想得到唯一的。这只是返回用户id,我只需要选择id,但是从唯一的用户id。嗯。。这很好,因为它提供了最新的用户id,但实际上这与我想要的正好相反。我用更好的描述编辑了我的答案,但我想要的只是来自唯一用户id的最新活动。很抱歉,问题写得不好。请使用表列的定义再次编辑问题。你说了一些关于created_at的话,但不清楚这是什么意思。另外,请阅读:OLAP只是一个花哨的商业术语——在线分析处理并没有真正传达任何意义,难怪一些大公司喜欢使用它。行号是PostgreSQL和SQL标准中的一个。。这很好,因为它提供了最新的用户id,但实际上这与我想要的正好相反。我用更好的描述编辑了我的答案,但我想要的只是来自唯一用户id的最新活动。很抱歉,问题写得不好。请使用表列的定义再次编辑问题。你说了一些关于created_at的话,但不清楚这是什么意思。另外,请阅读:OLAP只是一个花哨的商业术语——在线分析处理并没有真正传达任何意义,难怪一些大公司喜欢使用它。行号是PostgreSQL和SQL标准中的一个。非常好的答案,谢谢。我只想知道最近的id,不是总数,但我能猜出来。非常好的答案,谢谢。只需要最新的id,而不是聚合的id,但我可以找到那个id。