SQL服务器-各列统计模式
SQL Server - statistical Mode of each column
对于给定的 table,我想要一个 SQL 查询,其中 returns 单个记录集中每一列的统计模式。我看到了几种通过聚合来做到这一点的方法,但它们都是单列方法。任何人都可以想出一种方法来执行此操作,而无需合并与列一样多的查询吗? SQL 服务器中没有 mode() 聚合。
如果table #x 有 3 列,我想要单行有 3 列。这是使用 SQL 服务器的示例。这是很多繁重的工作,而且非常适合 table 定义。我正在寻找一种更清洁、更通用的方法。我可能想在不同的时间在不同的 table 上执行此操作。
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
这将动态生成 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
Returns
Item Value Hits
age 20 4
city NYC 10
name Bill 7
对于给定的 table,我想要一个 SQL 查询,其中 returns 单个记录集中每一列的统计模式。我看到了几种通过聚合来做到这一点的方法,但它们都是单列方法。任何人都可以想出一种方法来执行此操作,而无需合并与列一样多的查询吗? SQL 服务器中没有 mode() 聚合。
如果table #x 有 3 列,我想要单行有 3 列。这是使用 SQL 服务器的示例。这是很多繁重的工作,而且非常适合 table 定义。我正在寻找一种更清洁、更通用的方法。我可能想在不同的时间在不同的 table 上执行此操作。
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
这将动态生成 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
Returns
Item Value Hits
age 20 4
city NYC 10
name Bill 7