SQL Server - 每列的统计模式

时间:2016-08-15 14:34:52

标签: sql-server aggregate-functions mode

对于给定的表,我想要一个SQL查询,它返回单个记录集中每列的统计模式。我看到了使用聚合的几种方法,但它们都是单列方法。任何人都可以想到一种方法来做到这一点,而不需要像列一样多的查询的联合? SQL Server中没有mode()聚合。

如果表#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

1 个答案:

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