【问题标题】:SQL Server - statistical Mode of each columnSQL Server - 每列的统计模式
【发布时间】:2016-12-21 18:45:54
【问题描述】:

对于给定的表,我想要一个 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

【问题讨论】:

  • 你能用一些示例数据解释一下并发布预期结果
  • 更新了示例和所需的输出。

标签: sql-server aggregate-functions mode


【解决方案1】:

这将动态生成项目、价值和命中。您可以根据需要进行旋转。

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

【讨论】:

  • 有点开箱即用,因为它使用我不熟悉的 XML 数据类型。但它似乎适用于你扔给它的任何桌子。谢谢。
  • @bvy 这就是他们的想法。我是一个懒惰的编码员,我宁愿写一次,让它服务于多个主人。我是 XML 的迟到者。我希望我早点采用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
相关资源
最近更新 更多