【问题标题】:Selecting rows with the most repeated values at specific column选择特定列中重复值最多的行
【发布时间】:2021-02-06 21:38:12
【问题描述】:

问题笼统地说:我需要从一个表中选择一个引用另一个表中重复次数最多的值的值。

表具有以下结构: screenshot screenshot2

问题是找到与它相关的运动员的成绩最多的国家。

首先,INNER JOIN 表在结果和国家/地区之间建立关系

SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id);

然后,我计算每个国家出现的时间

SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
    INNER JOIN sportsman USING (sportsman_id))
GROUP BY country
;

得到了这个screenshot3

现在感觉我离解决方案只有一步之遥)) 我想可以再使用一个 SELECT FROM (SELECT ...) 和 MAX() 但我无法结束它?

ps: 我通过将这样的查询加倍来做到这一点,但如果有数百万行,我觉得效率太低了。

SELECT country 
    FROM (SELECT country, COUNT(country) AS highest_participation
        FROM (SELECT competition_id, country FROM result 
            INNER JOIN sportsman USING (sportsman_id) 
            ) GROUP BY country 
        ) 
WHERE highest_participation = (SELECT MAX(highest_participation)  
    FROM (SELECT country, COUNT(country) AS highest_participation
        FROM (SELECT competition_id, country FROM result 
            INNER JOIN sportsman USING (sportsman_id) 
            ) GROUP BY country 
        ))

我也是用视图来做的

CREATE VIEW temp AS 
    SELECT country as country_with_most_participations, COUNT(country) as country_participate_in_#_comp 
    FROM( 
        SELECT country, competition_id FROM result 
        INNER JOIN sportsman USING(sportsman_id)
        ) 
    GROUP BY country;
SELECT country_with_most_participations FROM temp 
WHERE country_participate_in_#_comp = (SELECT MAX(country_participate_in_#_comp) FROM temp);

但不确定这是否是最简单的方法。

【问题讨论】:

    标签: sql oracle count sql-order-by inner-join


    【解决方案1】:

    如果我理解正确,您希望按比赛计数对国家/地区进行排名,并显示排名最高的国家(或多个国家)及其计数。我建议您使用RANK 进行排名。

    select country, competition_count
    from
    (
      select 
        s.country,
        count(*) as competition_count,
        rank() over (order by count(*) desc) as rn
      from sportsman s
      inner join result r using (sportsman_id)
      group by s.country
    ) ranked_by_count
    where rn = 1
    order by country;
    

    如果结果行的顺序无关紧要,您可以将其缩短为:

    select s.country, count(*) as competition_count      
    from sportsman s
    inner join result r using (sportsman_id)
    group by s.country
    order by count(*) desc
    fetch first rows with ties;
    

    【讨论】:

    • 谢谢。第二个查询正是我想要的。当可能有多个最高值时,“获取有关系的第一行”似乎非常有用。
    【解决方案2】:

    您似乎过于复杂了。从现有的 join 查询开始,您可以聚合、排序结果并仅保留最上面的行。

    select s.country, count(*) cnt
    from sportsman s
    inner join result r using (sportsman_id)
    group by s.country
    order by cnt desc
    fetch first 1 row with ties
    

    请注意,如果有的话,这允许顶级关系。

    【讨论】:

    • 我猜你的意思是 INNER 不交叉。否则就是这样。 ty
    • @void_eater:当然。固定。
    【解决方案3】:
    SELECT country 
        FROM (SELECT country, COUNT(country) AS highest_participation
            FROM (SELECT competition_id, country FROM result 
                INNER JOIN sportsman USING (sportsman_id) 
                ) GROUP BY country 
    order by 2 desc
            ) 
    where rownum=1
    

    【讨论】:

    • 如果有多个 MAX 会丢失值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 2014-01-04
    • 1970-01-01
    • 2014-03-03
    相关资源
    最近更新 更多