按组

时间:2018-03-17 00:48:00

标签: sql sql-server

我有一个表格,用户可以设置对给定事件的反应/投票,我希望能够创建一个摘要视图,以查看大多数时候投票的反应,除以每个事件的组。

样本数据如下:

DECLARE @voteTable AS TABLE (
    id              INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
    eventId     VARCHAR(255) NOT NULL
,   isGroupA    INT NOT NULL
,   isGroupB    INT NOT NULL
,   userVote    VARCHAR(255) NOT NULL
);


INSERT INTO @voteTable (eventId, isGroupA, isGroupB, userVote)
VALUES
('event1','0','0','fantastic'),
('event1','0','0','fantastic'),
('event1','0','0','fantastic'),
('event1','0','0','fantastic'),
('event1','0','0','fantastic'),
('event1','0','0','fantastic'),
('event1','0','0','meh'),
('event1','0','0','meh'),
('event1','1','0','fine'),
('event1','1','0','fine'),
('event1','1','0','great'),
('event1','1','0','ok'),
('event1','1','0','ok'),
('event1','1','0','ok'),
('event1','0','1','fine'),
('event1','0','1','great'),
('event1','0','1','great'),
('event1','0','1','ok'),
('event1','1','1','bad'),
('event1','1','1','bad'),
('event1','1','1','horrible'),
('event1','1','1','horrible'),
('event1','1','1','horrible'),
('event1','1','1','horrible'),
('event1','1','1','horrible'),
('event1','1','1','ok'),
('event2','0','0','fantastic'),
('event2','0','0','fantastic'),
('event2','0','0','fantastic'),
('event2','0','0','horrible'),
('event2','0','0','fantastic'),
('event2','0','0','fantastic'),
('event2','0','0','fine'),
('event2','0','0','great'),
('event2','1','0','meh'),
('event2','1','0','meh'),
('event2','1','0','ok'),
('event2','1','0','ok'),
('event2','1','0','ok'),
('event2','1','0','ok'),
('event2','0','1','bad'),
('event2','0','1','bad'),
('event2','0','1','bad'),
('event2','0','1','bad'),
('event2','1','1','fine'),
('event2','1','1','fine'),
('event2','1','1','great'),
('event2','1','1','great'),
('event2','1','1','ok'),
('event2','1','1','bad'),
('event2','1','1','ok'),
('event2','1','1','ok')

我想得到的输出应该是:

eventId |  groupA  |  groupB  | everyone
----------------------------------------
 event1 | horrible | horrible | fantastic
 event2 |    ok    |    bad   |    ok

原因是event1:

  • 那些以1为isGroupA投票的人#34;可怕" 5倍,超过任何 其他投票类型。
  • 那些拥有1 for isGroupB的人也投了#34;可怕的" 5倍以上 任何其他投票。
  • 无论group1为什么,投票数最多 真是太棒了。"

类似于event2:

  • 在团体A中投票的人#34; ok" 7次,超过任何其他投票。
  • B组中的人投票"糟糕" 5次,超过任何其他投票。
  • 无论小组如何,具有最高频率的投票类型是" ok"

我希望我的问题清楚。如果我不清楚或者我是否需要澄清任何事情,请告诉我。

我正在考虑使用COUNT(isGroupA) as aVotes做一些事情,按eventId和userVote进行分组并使用RANK()函数,但我似乎无法理解如何构建整体查询。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

您正在寻找模式。获得此功能的一种方法是使用聚合和窗口函数:

select eventid,
       max(case when grp = 'A' then uservote end) as groupA,
       max(case when grp = 'B' then uservote end) as groupB,
       max(case when grp = 'Both' then uservote end) as both 
from (select eventid, uservote, grp, count(*) as cnt,
             row_number() over (partition by eventid, grp order by count(*) desc) as seqnum
      from votetable vt cross apply
           (values (case when isGroupA = '1' then 'A' end),
                   (case when isGroupB = '1' then 'b' end),
                   ('Both')
           ) v(grp)
      where grp is not null
      group by eventid, uservote, grp
     ) eg
where seqnum = 1
group by eventId;

Here是一个SQL小提琴。

答案 1 :(得分:1)

使用Cte表

;
with CteCount as(
Select eventId, isGroupA, null as isGroupB,
ROW_NUMBER() over (Partition by eventId, isGroupA, UserVote Order by eventId, isGroupA, UserVote) as isGroupACount,
null as isGroupBCount,
null as isAllCount,
uservote
from @voteTable
where isGroupA = 1

UNION ALL

Select eventId, null as isGroupA, isGroupB,
null,
ROW_NUMBER() over (Partition by eventId, isGroupB, UserVote Order by eventId, isGroupB, UserVote) as isGroupBCount,
null,
uservote
from @voteTable
where isGroupB = 1

UNION ALL

Select eventId, null as isGroupA, null as isGroupB, 
null,
null,
ROW_NUMBER() over (Partition by eventId, UserVote Order by eventId, UserVote) as isAllCount,
uservote
from @voteTable
),
CteSummary as(
Select eventId,
max(isGroupACount) as GroupA,
max(isGroupBCount) as GroupB,
max(isAllCount) as isAll
from CteCount
Group by eventId
)
Select
*,
(Select a.userVote from CteCount a where a.isGroupA = 1 and isGroupACount = GroupA and a.eventId = CteSummary.eventId) as GroupAvote,
(Select a.userVote from CteCount a where a.isGroupB = 1 and isGroupBCount = GroupB and a.eventId = CteSummary.eventId) as GroupBvote,
(Select a.userVote from CteCount a where a.isAllCount = isAll and a.eventId = CteSummary.eventId) as Allvote

from CteSummary