2016-09-29 68 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)