2016-08-15 1 views
-2

Для данной таблицы мне нужен SQL-запрос, который возвращает статистический режим каждого столбца в одном наборе записей. Я вижу несколько способов сделать это с помощью агрегации, но они все подходы с одним столбцом. Может ли кто-нибудь подумать о способе сделать это, не принимая объединение столько запросов, сколько есть столбцов? В SQL Server нет агрегата mode().SQL Server - статистический режим для каждого столбца

Если таблица #x имеет 3 столбца, я хочу одну строку с 3 столбцами. Вот пример использования SQL Server. Это очень тяжелый подъем и очень скроенный для определения таблицы. Я ищу более чистый, более обобщенный подход. Возможно, я захочу сделать это на разных таблицах в разное время.

create table #x (name varchar(20), age int, city varchar(20)) 
insert into #x values ('Bill', 20, 'NYC') 
insert into #x values ('Bill', 15, 'NYC') 
insert into #x values ('Mary', 29, 'LA') 
insert into #x values ('Bill', 30, 'NYC') 
insert into #x values ('Bill', 30, 'NYC') 
insert into #x values ('Bill', 20, 'LA') 
insert into #x values ('Mary', 20, 'NYC') 
insert into #x values ('Joe', 12, 'NYC') 
insert into #x values ('Fred', 55, 'NYC') 
insert into #x values ('Alex', 41, 'NYC') 
insert into #x values ('Alex', 30, 'LA') 
insert into #x values ('Alex', 10, 'Chicago') 
insert into #x values ('Bill', 20, 'NYC') 
insert into #x values ('Bill', 10, 'NYC') 

create table #modes (_column varchar(20), _count int, _mode varchar(20)) 
insert into #modes select top 1 'name' _column, count(*) _count, name _mode from #x group by name order by 2 desc 
insert into #modes select top 1 'age' _column, count(*) _count, age _mode from #x group by age order by 2 desc 
insert into #modes select top 1 'city' _column, count(*) _count, city _mode from #x group by city order by 2 desc 

select name, age, city from (select _mode, _column from #modes) m 
pivot (max(_mode) for _column in (name, age, city)) p 
+0

Можете ли вы объяснить, с некоторыми образцами данных и пост ожидаемого результата – TheGameiswar

+0

Обновленные с примером и желаемых результатов. – bvy

ответ

0

Это будет динамически генерировать Item, Value и Hits. Вы можете поворачиваться по своему усмотрению.

Declare @YourTable table (name varchar(20), age int, city varchar(20)) 
Insert Into @YourTable values 
('Bill', 20, 'NYC'), 
('Bill', 15, 'NYC'), 
('Mary', 29, 'LA'), 
('Bill', 30, 'NYC'), 
('Bill', 30, 'NYC'), 
('Bill', 20, 'LA'), 
('Mary', 20, 'NYC'), 
('Joe', 12, 'NYC'), 
('Fred', 55, 'NYC'), 
('Alex', 41, 'NYC'), 
('Alex', 30, 'LA'), 
('Alex', 10, 'Chicago'), 
('Bill', 20, 'NYC'), 
('Bill', 10, 'NYC') 

Declare @XML xml 
Set @XML = (Select * from @YourTable for XML RAW) 

Select Item,Value,Hits 
From (
     Select Item,Value,Hits=count(*),RowNr = ROW_NUMBER() over (Partition By Item Order By Count(*) Desc) 
     From (
       Select ID = r.value('@id','int')       -- Usually Reserved 
         ,Item = Attr.value('local-name(.)','varchar(100)') 
         ,Value = Attr.value('.','varchar(max)') 
       From @XML.nodes('/row') as A(r) 
       Cross Apply A.r.nodes('./@*[local-name(.)!="id"]') as B(Attr) 
      ) A 
     Group By Item,Value 
    ) A 
Where RowNr=1 

Возвращает

Item Value Hits 
age  20  4 
city NYC  10 
name Bill 7 
+0

Немного из коробки, поскольку он использует тип данных XML, с которым я не знаком. Но, похоже, он работает с любой таблицей, которую вы бросаете на нее. Спасибо. – bvy

+0

@bvy Это была идея. Я ленивый кодер, я бы лучше написал что-то один раз и давал ему сервер нескольких мастеров. Я был поздним поклонником XML. Хотелось бы, чтобы я принял его раньше. –

Смежные вопросы