【问题标题】:How to get the values for every group of the top 3 types如何获取前 3 种类型的每组的值
【发布时间】:2021-09-11 19:12:39
【问题描述】:

我有这张桌子ratings

id user_id type value
0 0 Rest 4
1 0 Bar 3
2 0 Cine 2
3 0 Cafe 1
4 1 Rest 4
5 1 Bar 3
6 1 Cine 2
7 1 Cafe 5
8 2 Rest 4
9 2 Bar 3
10 3 Cine 2
11 3 Cafe 5

我希望有一个表格,每对 (user_id, type) 对应所有用户中排名前 3 的类型(在整个表格中按 sum(value) 排名)。

想要的结果:

user_id type value
0 Rest 4
0 Cafe 1
0 Bar 3
1 Rest 4
1 Cafe 5
1 Bar 3
2 Rest 4
3 Cafe 5
2 Bar 3

我可以通过两个查询来做到这一点,一个是获取前 3 个,另一个是获取类型与前 3 个类型匹配的行。

有人知道如何将其放入单个查询中吗?

【问题讨论】:

  • 我不太明白输出。为什么用户 3 只有一行,为什么用户 0 有 Cafe 而不是 Cine?
  • 因为我想要的前 3 名不在组内,而是在所有收视率内。前 3 种类型是:Rest -> 12 Cafe -> 11 Bar -> 9 因此过滤行以仅显示对前 3 种类型进行评分的行

标签: sql postgresql aggregate greatest-n-per-group


【解决方案1】:

我想你只是想要row_number()。根据您的结果,您似乎需要每种类型的三行,具有最高值:

select t.*
from (select t.*,
             row_number() over (partition by type order by value desc) as seqnum
      from t
     ) t
where seqnum <= 3;

您的描述表明您可能只希望每个用户都有这个,这是一个细微的调整:

select t.*
from (select t.*,
             row_number() over (partition by user order by value desc) as seqnum
      from t
     ) t
where seqnum <= 3;

【讨论】:

  • 看起来很不错,您介意解释一下 over / partition 位以澄清答案吗?
  • @BrunoLoops:你为什么接受这个答案?它显然不能满足您的要求。
  • @ErwinBrandstetter 感谢您的注意,感谢这个答案,我已经以另一种方式解决了它。但是,我无法确认 Gordon 建议的解决方案不正确,这就是我接受它的原因。现在你的答案看起来好多了,我会接受,谢谢
【解决方案2】:

为每个用户获取排名最高的 3 种类型的行,其中类型按其在整个表中的值的总和进行排名。

因此,这不完全是关于每个用户的前 3 种类型,而是关于总体上的前 3 种类型。并非所有用户都有前 3 种类型的行,即使该用户有 3 种或更多类型。

策略:
聚合以获取每种类型的总和值 (type_rnk)。
只拿前 3 名。(打破平局...)
加入主表,消除任何其他类型。
user_id, type_rnk DESC下单结果

SELECT r.user_id, r.type, r.value
FROM   ratings r
JOIN  (
   SELECT type, sum(value) AS type_rnk
   FROM   ratings
   GROUP  BY 1
   ORDER  BY type_rnk DESC, type  -- tiebreaker
   LIMIT  3   -- strictly the top 3
   ) v USING (type)
ORDER  BY user_id, type_rnk DESC;

db小提琴here

由于多种类型可以具有相同的排名,因此我在排序顺序中添加了type,以便按名称的字母顺序打破平局(因为您没有另外指定)。

事实证明,我们不需要window functions - 那些带有OVER 和可选的PARTITION 的。 (因为你在评论中问过)。

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    相关资源
    最近更新 更多