Выберите N наиболее частых значений столбца B для каждого значения столбца A - PullRequest
0 голосов
/ 05 апреля 2019

С таблицей 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 Я хочу найти N наиболее частых значений в colB.

Пример результата для N =2:

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

Я могу получить все уникальные комбинации colA и colB с их частотами, используя:

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

Но я изо всех сил пытаюсь применить LIMIT для каждого значения в colA вместо всей таблицы.

Это в основном похоже на Как выбрать наиболее частое значение в столбце для каждогоid group? , только для MySQL вместо PostgreSQL.

Я сейчас использую MariaDB 10.1.

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Используйте оконные функции, если можете:

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().

0 голосов
/ 05 апреля 2019

Для этого вы можете использовать пару 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);
...