2016-12-14 4 views
7

У меня есть таблица в SQL, который выглядит следующим образом:Как выбрать наиболее частое значение в столбце для каждой группы идентификаторов?

user_id | data1 
0  | 6 
0  | 6 
0  | 6 
0  | 1 
0  | 1 
0  | 2 
1  | 5 
1  | 5 
1  | 3 
1  | 3 
1  | 3 
1  | 7 

Я хочу написать запрос, который возвращает два столбца: столбец для идентификатора пользователя, и столбец за то, что наиболее часто встречающееся значение для каждого идентификатора является. В моем примере, для user_id 0, наиболее часто встречающееся значение составляет 6, а для user_id 1, наиболее часто встречающееся значение равно 3. Я хотел бы, чтобы это выглядело, как показано ниже:

user_id | most_frequent_value 
0  | 6 
1  | 3 

Я использую запрос ниже получить наиболее частое значение, но оно выполняется против всей таблицы и возвращает наиболее общее значение для всей таблицы, а не для каждого идентификатора. Что мне нужно добавить к моему запросу, чтобы он смог вернуть наиболее частое значение для каждого идентификатора? Я думаю, мне нужно использовать подзапрос, но я не уверен, как его структурировать.

SELECT user_id, data1 AS most_frequent_value 
FROM my_table 
GROUP BY user_id, data1 
ORDER BY COUNT(*) DESC LIMIT 1 
+1

Как насчет ничьей? (т. е. вы добавляете строку '(0, 1)' к вашему примеру, тогда как '6', так и' 1' являются наиболее частым значением, потому что оба они встречаются 3 раза). – pozs

ответ

2

Если вы используете правильный «заказ», то distinct on (user_id) делают ту же работу, потому что он принимает 1.Line из данных, разбитых на разделы «user_id». DISTINCT ON - специальность PostgreSQL.

select distinct on (user_id) user_id, most_frequent_value from (
SELECT user_id, data1 AS most_frequent_value, count(*) as _count 
FROM my_table 
GROUP BY user_id, data1) a 
ORDER BY user_id, _count DESC 
+0

могу я знать почему -1? Потому что я тестировал его на этом примере, и часто использую те же запросы .... – JosMac

+0

Это отлично работает - спасибо! Я тоже хотел бы знать, почему у него был -1 голос (это был не я) – cjh193

+0

Это может сработать, если OP не заботится о розыгрышах. – pozs

1

Вы можете использовать функцию окна, чтобы ранжировать идентификаторы пользователей по их количеству данных1.

; WITH cte AS (
SELECT 
    user_id 
    , data1 
    , ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY COUNT(data1) DESC) rn 
FROM dbo.YourTable 
GROUP BY 
    user_id, 
    data1) 

SELECT 
    user_id, 
    data1 
FROM cte WHERE rn = 1 
2

С postgres 9.4 или больше можно. Вы можете использовать его как:

SELECT 
    user_id, MODE() WITHIN GROUP (ORDER BY value) 
FROM 
    (VALUES (0,6), (0,6), (0, 6), (0,1),(0,1), (1,5), (1,5), (1,3), (1,3), (1,7)) 
    users (user_id, value) 
GROUP BY user_id