【问题标题】:SQL FOR XML PATH list and COUNTSQL FOR XML PATH 列表和 COUNT
【发布时间】:2011-05-20 15:41:29
【问题描述】:

我有一张桌子,例如:

|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]

还有更优雅的查询吗?

【问题讨论】:

  • 不,我认为目前对于 SQL Server 来说没有更简单或“更优雅”的代码
  • 劳伦斯,我不确定你的意思。这是直接针对服务器执行的事务 SQL。
  • 我基本上想知道是否可以在一个查询中执行此操作,而不是将两个子查询连接在一起。

标签: sql-server for-xml-path


【解决方案1】:
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]

如果您认为 Name 列可能包含 <>'"&,您应该这样做:

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]

【讨论】:

  • 谢谢 Mikael,就是这样。不知道为什么我昨天不能让它工作。
【解决方案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)作为您自己的列名和/或表名......它总是相当混乱......

【讨论】:

  • 所以你会对SELECT [SELECT] FROM [FROM] WHERE [WHERE] = 'WHERE'提出异议?
  • @呸:呸!! :-) 是的,这似乎有点“不愉快” :-)
  • @Yuck - 也可以添加这些GROUP BY [GROUP BY] ORDER BY [ORDER BY]
猜你喜欢
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
相关资源
最近更新 更多