#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть таблица (DeviceOS2), и я хотел бы получить наиболее частое значение для каждого столбца (ОС и устройства) для каждого идентификатора.
ID OS Device
123 OSX Mac
123 OSX PC
123 OSX PC
123 Android Tablet
Желаемый результат:
ID OS Device
123 OSX PC
Однако мой код теперь дает мне следующее:
ID OS Device
123 Android Tablet
123 OSX Mac
123 OSX PC
Похоже, он подбирает каждую комбинацию.
Текущий код (T-SQL):
Select
ID,
OS,
Device
FROM(
Select
ID,
OS,
Device
FROM DeviceOS2
Group By ID,OS,Device) a
Group By ID,OS,Device
Ответ №1:
Попробуйте это:
select top 1 with ties a.ID, a.OS,a.Device
from (
select d.ID, d.OS, d.Device, ROW_NUMBER () over (partition by d.OS, d.Device order by id) rnk
from DeviceOS2 d)a
order by a.rnk desc
Обновить
Если вам нужно наиболее частое значение для каждого идентификатора:
select c.ID,c.OS,c.Device from (
select d.ID, d.OS, d.Device, ROW_NUMBER () over (partition by d.id, d.OS, d.Device order by id) rnk
from DeviceOS2 d)c
join
(
select a.ID,max(a.rnk) AS rnk
from (
select d.ID, d.OS, d.Device, ROW_NUMBER () over (partition by d.id, d.OS, d.Device order by id) rnk
from DeviceOS2 d)a
group by a.ID) a
on c.ID = a.ID and a.rnk = c.rnk
Комментарии:
1. Спасибо! Однако в моих реальных данных у меня много идентификаторов. Как я могу получить этот результат для каждого идентификатора, который у меня есть, пожалуйста. Еще раз спасибо 🙂
Ответ №2:
Вы могли бы использовать:
SELECT TOP 1 WITH TIES *
FROM tab
ORDER BY COUNT(*) OVER(PARITIION BY ID,OS) DESC
Ответ №3:
Это называется режимом. Вы можете использовать оконные функции:
select o.*
from (select os, device, count(*) as cnt,
row_number() over (partition by os order by count(*) desc) as seqnum
from DeviceOS2
group by os, device
) o
where seqnum = 1;
Если вам нужна наиболее частая комбинация, используйте:
select os, device, count(*) as cnt
from DeviceOS2
group by os, device
order by count(*) desc
fetch first 1 row only;
(или используйте select top (1)
, если вы предпочитаете).
Редактировать:
Для вашего отредактированного вопроса:
select o.*
from (select os, device, count(*) as cnt,
row_number() over (partition by os order by count(*) desc) as seqnum
from DeviceOS2
group by os, device
) o
where seqnum = 1;
Если вам нужна наиболее частая комбинация, тогда запрос немного сложнее. Один метод — это две агрегации:
select o.id,
max(case case when o.seqnum = 1 then os end) as most_frequent_os,
max(case case when d.seqnum = 1 then device end) as most_frequent_device
from (select id, os, count(*) as cnt,
row_number() over (partition by id order by count(*) desc) as seqnum
from DeviceOS2
group by id, os
) o join
(select id, device, count(*) as cnt,
row_number() over (partition by id order by count(*) desc) as seqnum
from DeviceOS2
group by id, device
) d
on d.id = o.id
Комментарии:
1. Спасибо! Однако, когда я его запускаю, я также получаю строку с
Android Tablet
. Как я могу получить толькоOSX PC
пожалуйста.2. @яблоки-апельсины . , , Я интерпретировал вопрос как наиболее частое устройство для каждой ОС.
3.А, ладно! Спасибо, приятель 🙂 Пожалуйста, завершите: как получить наиболее частое значение для каждого отдельного столбца, для каждого
ID
(в моем примереID
показан только один). Так что дляID
123
,OSX
является наиболее частымOS
. Аналогично дляDevice
, наиболее частым являетсяPC
. Следовательно, результирующая таблица предназначенаOSX PC
дляID
123
. Еще раз спасибо! 🙂