4

我有一张这样的桌子:

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 中做到这一点?我可以逐行进行分组吗?

4

2 回答 2

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

于 2013-08-29T14:43:04.087 回答
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;
于 2013-08-29T14:37:41.527 回答