2011-05-20 58 views
2

我有一個表,如:SQL FOR XML路徑列表COUNT

|Date   |Name| 
-------------------- 
|'20-May-2011'|Bob | 
|'20-May-2011'|Fred| 
|'20-May-2011'|Jim | 
|'21-May-2011'|Bob | 
|'21-May-2011'|Ed | 
|'22-May-2011'|Bill| 

我需要一個查詢返回:

|Date   |Count|Names   | 
-------------------------------------- 
|'20-May-2011'| 3|'Bob, Fred, Jim'| 
|'21-May-2011'| 2|'Bob, Ed'  | 
|'22-May-2011'| 1|'Bill'   | 

換句話說,我希望有一個列表和計數按日期排列的名稱。 我能想出的最好的是:

SELECT list.[Date], [Count], [Names] 
FROM (
    SELECT [Date], 
      STUFF((
       SELECT ', ' + [Name] 
       FROM #table t2 
       WHERE t2.[Date] = t.[Date] 
       ORDER BY [Name] 
       FOR XML PATH('') 
      ), 1, 2, '') AS [Names] 
    FROM #table t 
    GROUP BY [Date] 
) [list] 
INNER JOIN (
    SELECT [Date], 
      COUNT(*) AS [Count] 
    FROM #table t 
    GROUP BY [Date] 
) [count] 
    ON list.[Date] = count.[Date] 
ORDER BY [Count] DESC, list.[Date] 

是否有一個更優雅的查詢?

+0

不,我不認爲現在有什麼比這更簡單或更「優雅」的SQL Server代碼 – 2011-05-20 15:49:39

+0

勞倫斯,我不確定你的意思。這是交易SQL直接對服務器執行.. – 2011-05-20 16:24:06

+0

我基本上想知道是否有可能在一個查詢中做到這一點,而不是兩個子查詢連接在一起。 – 2011-05-20 16:24:46

回答

5
SELECT [Date], 
     COUNT(*) AS [Count], 
     STUFF((
      SELECT ', ' + [Name] 
      FROM #table t2 
      WHERE t2.[Date] = t.[Date] 
      ORDER BY [Name] 
      FOR XML PATH('') 
     ), 1, 2, '') AS [Names] 
FROM #table t 
GROUP BY [Date] 

如果你認爲名稱列中可能包含<>'"&你應該做這樣的替代:

SELECT [Date], 
     COUNT(*) AS [Count], 
     STUFF((
      SELECT ', ' + [Name] 
      FROM #table t2 
      WHERE t2.[Date] = t.[Date] 
      ORDER BY [Name] 
      FOR XML PATH(''), TYPE 
     ).value('.', 'varchar(max)'), 1, 2, '') AS [Names] 
FROM #table t 
GROUP BY [Date] 
+0

謝謝Mikael,就是這樣。不知道爲什麼我昨天無法工作。 – 2011-05-21 18:04:26

2

沒有太多好處 - 但也許使用單個CTE將XML-PATH填充「封裝」爲更具代表性的方式會起作用?

;WITH ConsolidatedData AS 
(
SELECT 
    [Date], 
    STUFF((
       SELECT ', ' + [Name] 
       FROM #table t2 
       WHERE t2.[Date] = t.[Date] 
       ORDER BY [Name] 
       FOR XML PATH('') 
      ), 1, 2, '') AS [Names] 
    FROM #table t 
) 
SELECT 
    [Date], Names, COUNT(*) 
FROM 
    ConsolidatedData 
GROUP BY 
    [Date], Names 

不知道如果你算上這是一個「複合」語句,或兩個.... :-)建議

一個字:儘量不要使用SQL Server標識符和保留字(如DateOrder)作爲自己的列和/或表名稱....它總是相當混亂....

+4

所以你會採取'SELECT [SELECT] FROM [FROM] WHERE [WHERE] ='WHERE''的問題? – Yuck 2011-05-20 17:15:36

+1

@Yuck:YUCK !! :-)是的,這似乎是一個「不愉快的」:-) – 2011-05-20 17:18:30

+4

@Yuck - 也可以添加這些'GROUP BY [GROUP BY] ORDER BY [ORDER BY]' – 2011-05-20 17:18:48