【问题标题】:Select N most frequent values of column B for each value of column A为列 A 的每个值选择列 B 的 N 个最频繁值
【发布时间】:2019-08-27 13:27:41
【问题描述】:

使用 MySQL 表,例如:

id | colA | colB
...| 1    | 13
...| 1    | 13
...| 1    | 12
...| 1    | 12
...| 1    | 11
...| 2    | 78
...| 2    | 78
...| 2    | 78
...| 2    | 13
...| 2    | 13
...| 2    | 9

对于colA 中的每个值,我想找到colB 中出现频率最高的N 个值。

N=2 的示例结果:

colA | colB
1    | 13
1    | 12
2    | 78
2    | 13

我可以使用以下方法获得 colAcolB 的所有独特组合及其频率:

SELECT colA, colB, COUNT(*) AS freq FROM t GROUP BY colA, colB ORDER BY freq DESC;

示例结果:

colA | colB | freq
1    | 13   | 2
1    | 12   | 2
1    | 11   | 1
2    | 78   | 3
2    | 13   | 2
2    | 9    | 1

但我很难为colA 中的每个值而不是整个表应用LIMIT

这基本上就像How to select most frequent value in a column per each id group?,只是用于 MySQL 而不是 PostgreSQL。

我目前正在使用 MariaDB 10.1。

【问题讨论】:

  • 你的主键是什么?
  • colAcolB 都不是主键。
  • 查看我添加的标签。

标签: mysql select mariadb groupwise-maximum


【解决方案1】:

您可能可以为此使用几个 CTE,例如:

WITH counts AS (
   SELECT colA, colB, COUNT(*) AS freq FROM t GROUP BY colA, colB ORDER BY freq DESC
), most_freq AS (
   SELECT colA, max(freq) FROM counts GROUP BY colA
)
   SELECT counts.*
     FROM counts
     JOIN most_freq ON (counts.colA = most_freq.colA 
                        AND counts.freq = most_freq.freq);

【讨论】:

    【解决方案2】:

    如果可以的话,使用窗口函数:

    SELECT colA, colB, freq
    FROM (SELECT colA, colB, COUNT(*) AS freq,
                 DENSE_RANK() OVER (PARTITION BY colA ORDER BY COUNT(*) DESC) as seqnum
          FROM t
          GROUP BY colA, colB 
         ) ab
    WHERE seqnum <= 2;
    

    请注意,您可能需要DENSE_RANK()RANK()ROW_NUMBER(),具体取决于您要如何处理关系。如果有 5 个 colB 值具有两个最高等级,则 DENSE_RANK() 将返回所有五个。

    如果您想要两个值,请使用ROW_NUMBER()

    【讨论】:

      猜你喜欢
      • 2017-04-30
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      相关资源
      最近更新 更多