【问题标题】:Finding the rank of a value in a most common list在最常见的列表中查找值的排名
【发布时间】:2021-03-07 10:51:05
【问题描述】:

我有一个包含一些名称和一些数字的数据库表,如下所示:

first last    number
max   muster  1
max   juster  2
max   huster  3
jen   muster  4
jen   jenker  5
ian   hoster  6
...

我通过以下方式查询最常见的名字:

SELECT first, COUNT(*) AS value FROM table
GROUP BY first
ORDER BY COUNT(*) DESC
LIMIT 3

我想知道这个数据库表的名字“ian”的排名。在这种情况下,它是第三个常见的名字,上面的查询给了我以下信息:

    first value
1   max   3
2   jen   2
3   ian   1

我想要的是以下代码:

    first value
3   ian   1

或类似的东西,这样我就可以通过给出first='ian' 来达到数字“3”,因为它是我表中的第三个通用名称。我该如何查询呢?

示例:

SELECT first, COUNT(*) AS value FROM table
GROUP BY first
ORDER BY COUNT(*) DESC

# So far we ordered the list from most common to least common

FILTER WHERE first='ian'

# We filtered the other names so that only first='ian' stays in the query,
# and we did not lose the index value (in this case 3) of the 'ian'

这行不通,但我想你明白我在寻找什么。

【问题讨论】:

标签: sql count sql-order-by where-clause rank


【解决方案1】:

你可以使用窗口函数:

select *
from (
    select first_name, count(*) as cnt, rank() over(order by count(*) desc) as rn
    from mytable
    group by first_name
) t
where first_name = 'ian'

这会给你“伊恩”的等级。

【讨论】:

  • 上面的代码 where first='ian' 生成一个只有 ian 的表,而 ian rank 将为 1,因为它是该表中的唯一条目
  • @oakca:查询执行您的要求。子查询对所有记录进行排名,然后在目标 name 上过滤外部查询。请尝试查询。
  • 你是对的。对不起,我没有复制粘贴你写的代码,因此不知何故我有错误的输出。我有一些问题,但请在你的答案中回答(所以你编辑,我将能够投票)。 1)这个't'是什么?它在你的代码中做了什么? 2) 排名的列名似乎为“m”。这是为什么?你在哪里定义它? @GMB
  • @oakca: t 是子查询的别名。不过,查询中没有 m
  • >查询中没有m。 >> 但不知何故,我的排名栏的名称似乎是m。而且我不知道为什么 pgAdmin4 决定给这个名字。 @GMB
【解决方案2】:

你可以这样做: (适用于 PostgreSQL)

SELECT * from
(
  select ROW_NUMBER() over (ORDER BY value desc) AS rownumber, firstname, value
  from
  (
    SELECT firstname, COUNT(*) AS value
    FROM public.people as pp
    GROUP BY firstname
  ) as goo
) AS foo
WHERE foo.firstname like 'ian%';

这给出了预期的结果:

3   ian                     1

或者如果你想获得第三个结果:

SELECT * from
(
  select ROW_NUMBER() over (ORDER BY value desc) AS rownumber, firstname, value
  from
  (
    SELECT firstname, COUNT(*) AS value
    FROM public.people as pp
    GROUP BY firstname
  ) as goo
) AS foo
WHERE rownumber = 3

或者如果你想像这样限制中间结果:

SELECT * from
(
  select ROW_NUMBER() over (ORDER BY value desc) AS rownumber, firstname, value
  from
  (
    SELECT firstname, COUNT(*) AS value
    FROM public.people as pp
    GROUP BY firstname
    ORDER BY COUNT(*) desc
    limit 3
  ) as goo
) AS foo
WHERE rownumber = 3

这给出了预期的结果:

3   ian                     1

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    相关资源
    最近更新 更多