【问题标题】:SQL Group-By most frequent [duplicate]SQL Group-By最频繁[重复]
【发布时间】:2017-10-27 06:20:54
【问题描述】:

假设我有下表

+-----------------------+----------------+
| PERSON                | ATE            |
+-----------------------+----------------+
| Joe                   | Chicken        |
| Joe                   | Chicken        |
| Joe                   | Chicken        |
| Joe                   | Tuna           |
| Joe                   | Tuna           |
| Joe                   | Chicken        |
| Joe                   | Tuna           |
| Joe                   | Chicken        |
| Joe                   | Tuna           |
| Joe                   | Tuna           |
| Joe                   | Tuna           |
| Joe                   | Chicken        |
| Joe                   | Tuna           |
| Joe                   | Tuna           |
| Joe                   | Chicken        |
| Joe                   | Tuna           |
| Joe                   | Tuna           |
| Joe                   | Tuna           |
| Rob                   | Chicken        |
| Rob                   | Tuna           |
| Rob                   | Chicken        |
| Rob                   | Chicken        |
| Rob                   | Chicken        |
| Rob                   | Chicken        |
| Jonathan              | Tuna           |
| Jonathan              | Tuna           |
| Jonathan              | Chicken        |
| Jonathan              | Tuna           |
| Jonathan              | Chicken        |
+-----------------------+----------------+

我想找出每个人最常吃的食物。所以,期望的结果是:

+-----------------------+----------------+
| PERSON                | ATE            |
+-----------------------+----------------+
| Joe                   | Tuna           |
| Rob                   | Chicken        |
| Jonathan              | Tuna           |
+-----------------------+----------------+

当然,我会 GROUP BY(人)。之后,我必须找到每组中最常吃的东西。如果它们是数字,那会很容易,因为我可以使用 MAX 函数,但我不知道如何从一堆字符串中挑选出最流行的字符串。

您将如何完成我在 SQL 中尝试做的事情?

【问题讨论】:

  • 计数,然后找到最大计数。
  • 最大计数将返回一个数字(计数)。然后我是否必须找到计数与 max_count 匹配的食物?这么简单的任务似乎有点复杂
  • @Naldhelaan 很简单,row_number mysql 仅支持版本 8 - dev.mysql.com/doc/refman/8.0/en/…
  • 所以这不是一张真正的桌子
  • 其实count会计算被吃掉的物品数量,而不是每个物品被吃掉的次数。我也必须 GROUP BY(ATE) 才能使您的建议起作用,因此我最初感到困惑

标签: mysql sql


【解决方案1】:

您可以使用相关子查询:

select distinct t1.PERSON, (
    select ATE
    from myTable t2
    where t2.PERSON = t1.PERSON
    group by ATE
    order by count(*) desc
    limit 1
) as ATE
from myTable t1

如果您有关系,此查询将“随机”选择最常吃的物品之一。

使用 MySQL 8 或 MariaDB 10.2(都还不稳定),您将能够使用 CTE(通用表表达式)

with t1 as (
    select PERSON, ATE, count(*) as cnt
    from myTable
    group by PERSON, ATE
), t2 as (
    select PERSON, max(cnt) as cnt
    from t1
    group by PERSON
)
    select *
    from t1
    natural join t2

在 tie 上,此查询可能会为每组 (PERSON) 返回多行。

【讨论】:

  • 哇,这么简单。我为发布如此复杂的答案而感到羞耻。
  • 可爱的解决方案,非常感谢。编辑:没有看到更新的答案
【解决方案2】:

通常,您必须多次汇总您的数据以获取每人和食物的计数,然后是每人,然后再次计数以进行比较...

但有一个技巧:将计数与食物粘在一起:

乔鸡 00000000000007鸡 乔金枪鱼 00000000000011金枪鱼 乔纳森鸡 00000000000002鸡 乔纳森金枪鱼 00000000000003金枪鱼 抢鸡 00000000000005鸡 抢金枪鱼 00000000000001金枪鱼

然后获取每个人的最大条目(例如00000000000011Tuna 为Joe)并去除数字:

select person, substr(max(combined), 15) as ate_most
from
(
  select person, concat(lpad(count(*), 14, '0'), ate) as combined
  from mytable
  group by person, ate
) trick
group by person
order by person;

http://rextester.com/GVO98572

【讨论】:

  • 感谢您的回答。不幸的是,这不能很好地扩展到生产系统,所以我犹豫要不要使用它
  • @Naldhelaan:你不使用它是对的。我想得太复杂了。 (这可能是因为我习惯了 Oracle,整个查询要简单得多:select person, stats_mode(ate) from mytable group by person。所以我不得不想一个比平常更复杂的模式并且做得过火了 :-) Paul 的回答比我的要好得多.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
  • 1970-01-01
相关资源
最近更新 更多