2016-09-29 35 views
-1

我有一个sql server中包含三列的表:“date”,“noon”和“3pm”。第一栏不言而喻,但后两栏则根据他们抵达的时间在会场中包含了演讲嘉宾的名字。我想编写一个跨标签查询,将发言人姓名写入列标题并计算发言人在该日发言的次数。SQL中的交叉表查询比较和添加列

Date | Noon | 3pm 
092916 | Tom | <null> 
092816 | Dick | Tom 
092716 | <null> | Suzy 

所需的输出

Date | Dick | Tom | Suzy 
092916 | <null> | 1 | <null> 
092816 | 1  | 1 | <null> 
092716 | <null> | <null> | 1 

我可以用一个交叉表查询做到这一点很容易地,如果我只能选择一个时间,把一个计数到价值范畴,但我多次合并时遇到问题,以便我可以准确计算谁在哪一天发言。

+0

你正在寻找的是单词'pivot' – ajeh

回答

0

您可以使用此查询:

select * 
from (
     select date, noon as speaker, count(*) as times 
     from  events 
     group by date, noon 
     union all 
     select date, [3pm], count(*) 
     from  events 
     group by date, [3pm] 
     ) as u 
pivot (
     sum(times) 
     for speaker in ([Dick], [Tom], [Suzy]) 
     ) as piv 
order by date desc; 

...,让你每个细胞计数(零,1或2):

Date | Dick | Tom | Suzy 
092916 | <null> | 1 | <null> 
092816 | 1 | 1 | <null> 
092716 | <null> | <null> | 1 
+0

谢谢您响应。由于有些发言者在同一天发言两次,我实际上需要点数。在5年的时间里,我也有50位演讲者,其中一些对于他们的时间段而言是独一无二的,这使得工会变得更加艰难,因为如果您单独调整每个时间段,那么会出现不同的列。 – anoddexperiment

+0

好吧,我更新了查询来做一个计数。当多个记录具有相同的日期时,'group by'子句是必需的。如果没有必要,可以选择删除它们,并用'1'替换count(*)。但是,如果您的扬声器数量不详,我建议您使用编程环境的功能。这更适合这一点。 – trincot

0

您可以动态构建查询。

这将为无论是在中午或下午3点列中找到每个名字的计数(情况)声明..类似COUNT(CASE WHEN 'Dick' IN ([Noon],[3pm]) THEN 1 END) as [Dick]

DECLARE @speakers NVARCHAR(MAX), 
     @sql NVARCHAR(MAX) 

SET @speakers = STUFF((
    SELECT ',COUNT(CASE WHEN ''' + [Name] + ''' IN ([Noon],[3pm]) THEN 1 END) as ' + QUOTENAME([Name]) 
    FROM (SELECT [Noon] AS [Name] FROM Table1 
      UNION ALL SELECT [3pm] FROM Table1) t 
    GROUP BY t.Name 
    FOR XML PATH('') 
), 1, 1, '') 

SET @sql = N'SELECT Date, ' + @speakers + ' FROM Table1 GROUP BY Date' 

--Print @sql to see what's going on 
EXEC(@sql)