分组依据并获得最常出现的明显价值

Tim*_*ter 5 sql group-by sql-server-2005

我想按varchar列进行分组,找到最常出现的foreignkey值.问题是可以将多个fiModel分配给相同的TAC(称为SSN_Number的15位数值的前8位).

这是一个带有sample-data的简化模型和查询:

create table #data(
    SSN_Number varchar(15),
    fiModel int
)
insert into #data
        SELECT '351806038155151',451 UNION ALL SELECT '353797028764243',232 UNION ALL SELECT '353797028764243',438 UNION ALL SELECT '353797028764243',438 UNION ALL SELECT '353797028764243',447 UNION ALL SELECT '358372015611578',318 UNION ALL SELECT '352045039834626',279 UNION ALL SELECT '352045031234567',279 UNION ALL SELECT '351806035647381',451 UNION ALL SELECT '352045037654321',207

--- following query returns all records(10)
select * from #data Order By SSN_Number

--- following query gives the distinct TAC's+fiModel, but TACs can repeat (9)
select substring(ssn_number,1,8)as TAC,fiModel,count(*) from #data
group by substring(ssn_number,1,8),fiModel
Order By substring(ssn_number,1,8),fiModel

--- following query gives the correct(distinct) TAC's (4), 
--- but i need the fiModel that occurs most often with the assigned TAC
--- if the number is the same, it doesn't matter what to take
select substring(ssn_number,1,8)as TAC,count(*) from #data
group by substring(ssn_number,1,8)
Order By substring(ssn_number,1,8)

drop table #data
Run Code Online (Sandbox Code Playgroud)

所以这是理想的结果:

TAC         fiModel
35180603    451
35204503    279
35379702    438
35837201    318
Run Code Online (Sandbox Code Playgroud)

Joh*_*n N 2

这应该可以解决问题(CTE 来救援!):

;with cte as (
    select substring(ssn_number,1,8) as TAC, fiModel, ROW_NUMBER() OVER (PARTITION BY substring(ssn_number,1,8) ORDER BY count(*) desc) as row
    from #data
    group by substring(ssn_number,1,8),fiModel
)
select TAC, fiModel
from cte
where row = 1
Run Code Online (Sandbox Code Playgroud)

作为子查询:

Select TAC,fiModel
from(
    Select substring(ssn_number,1,8)as TAC, fiModel
      ,ROW_NUMBER() OVER (PARTITION BY substring(ssn_number,1,8) ORDER BY count(*) desc) as row
    from #data
    group by substring(ssn_number,1,8),fiModel
)as data
where row=1
Run Code Online (Sandbox Code Playgroud)