每组获得最频繁的价值

时间:2019-04-11 16:30:12

标签: sql sql-server tsql

我有一个表(DeviceOS2),并希望每个ID的每一列(操作系统和设备)获得最频繁的值。

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

3 个答案:

答案 0 :(得分:1)

您可以使用:

SELECT TOP 1 WITH TIES *
FROM tab
ORDER BY COUNT(*) OVER(PARITIION BY ID,OS) DESC

答案 1 :(得分: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 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

答案 2 :(得分: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

更新

如果每个ID需要最频繁的ID:

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