我有一张这样的表:
Answer1,Answer2,Answer3,Answer4
A,B,C,C
B,D,D,D
C,C,A,C
B,B,D,D
我想找到所有四个答案的最多出现次数,如果出现次数相同,我只需要第一个值。理想情况下,我应该有一个这样的输出表:
Answer1,Answer2,Answer3,Answer4,MostAnswers,Occurrences
A,B,C,C,C,2
B,D,D,D,D,3
C,C,A,C,C,3
B,B,D,D,B,2
如何在sql server中执行此操作?我可以逐行进行分组吗?
答案 0 :(得分:5)
另一种方法仍然假设存在Id
列:
select
a.Id,
a.Answer1,
a.Answer2,
a.Answer3,
a.Answer4,
TopAnswers.*
from AnswerTable a
outer apply (
select top 1 Answer, count(*) as cnt
from (
select Answer1 as Answer from AnswerTable where Id = a.Id
union all
select Answer2 from AnswerTable where Id = a.Id
union all
select Answer3 from AnswerTable where Id = a.Id
union all
select Answer4 from AnswerTable where Id = a.Id
) x
group by Answer
order by count(*) desc, Answer asc
) TopAnswers
以下是SQLFiddle:http://sqlfiddle.com/#!3/b1dfd/8
答案 1 :(得分:1)
一种方法是取消数据的转移。诀窍是你需要一个id
来识别每一行。这是在以下查询中使用row_number()
获得的。然后获取所需的值需要明智地使用聚合和窗口函数:
with t as (
select (case when n.n = 1 then answer1
when n.n = 2 then answer2
when n.n = 3 then answer3
when n.n = 4 then answer4
end) as answer, a.*
from (select row_number() over (order by (select NULL)) as recnum, a.*
from answers a
) cross join
(select 1 as n union all select 2 union all select 3 union all select 4) n
)
select answer1, answer2, answer3, answer4, answer, cnt
from (select recnum, answer1, answer2, answer3, answer4, answer, count(*) as cnt,
row_number() over (partition by recnum order by count(*) desc
) as seqnum_cnt
from t
group by recnum, answer1, answer2, answer3, answer4, answer
) a
where seqnum_cnt = 1;