【问题标题】:How do I return the most common column value for each value in another column using mySQL?如何使用 mySQL 返回另一列中每个值的最常见列值?
【发布时间】:2020-03-29 18:44:45
【问题描述】:

我正在寻找一个棘手的 MySQL 查询来为另一列中的每个值返回最常见的列值。我可以使用 PHP 来处理每个结果,但是用一个查询来做会更酷:)

例如,如果有一个这样的表,称为“事务”:

Id  payee   exp     category    
1   Amazon  25.00   Gifts
2   Amazon  30.21   Books
3   Amazon  12.98   Gifts
4   Amazon  15.00   Groceries
5   Amazon  14.54   Gifts
6   Alibaba 55.55   Stock
7   Alibaba 99.00   Stock
8   Alibaba 12.00   Fun
…

我想要的结果是这样的:

payee   count(payee)    category
Amazon  3               Gifts
Alibaba 2               Stock
…

我可以这样做:

SELECT `payee`, COUNT(`payee`), `category` FROM `transactions` WHERE 1 GROUP BY category ORDER BY COUNT(`payee`) DESC 

并接近我想要的:

Amazon  3   Gifts
Alibaba 2   Stock
Amazon  1   Books
Amazon  1   Groceries
Alibaba 1   Fun

但我不想要非最大计数(例如 Amazon、1、Books)。

我必须做一个子查询吗?还是用在?

【问题讨论】:

    标签: mysql sql count greatest-n-per-group window-functions


    【解决方案1】:

    您可以使用having 子句中的相关子查询过滤现有查询的结果,如下所示:

    select payee, count(*), category 
    from transactions t
    group by payee, category 
    having count(*) = (
        select count(*) 
        from transactions t1 
        where t1.payee = t.payee 
        group by category
        order by count(*) desc limit 1
    )
    order by count(*) desc
    

    Demo on DB Fiddle

    收款人 |计数(*) |类别 :-------- | --------: | :-------- 亚马逊 | 3 |礼物 阿里巴巴 | 2 |库存

    或者,如果您正在运行 MySQL 8.0,您可以使用窗口函数 rank() over() 对每个收款人的类别进行排名,并过滤每个组的顶部记录:

    select payee, cnt, category
    from (
        select 
            payee, 
            count(*) cnt, 
            category, 
            rank() over(partition by payee order by count(*) desc) rn
        from transactions 
        group by category, payee
    ) t
    where rn = 1
    

    Demo on DB Fiddle

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 2020-11-17
      • 2017-11-08
      • 1970-01-01
      • 2021-05-21
      • 2011-04-16
      • 2014-09-15
      • 2021-10-16
      • 2021-10-09
      相关资源
      最近更新 更多