0

我正在尝试显示具有相同名称的表条目的数量以及与每个条目关联的唯一 ID。

所以我有一张这样的桌子......

Table Names
------------------------------
ID    Name
0    John
1    Mike
2    John
3    Mike
4    Adam
5    Mike

我希望输出类似于:

Name | Count | IDs
---------------------
Mike     3     1,3,5
John     2     0,2
Adam     1     4

除了显示所有唯一 ID 之外,我有以下查询:

select name, count(*) as ct from names group by name order by ct desc;
4

3 回答 3

3
select name,
       count(id) as ct, 
       group_concat(id) as IDs
from names
group by name
order by ct desc;

您可以为此使用GROUP_CONCAT

于 2012-08-06T17:46:56.433 回答
1

根据您使用的 MSSQL 版本(2005+),您可以使用该FOR XML PATH选项。

SELECT 
    Name, 
    COUNT(*) AS ct, 
    STUFF((SELECT ',' + CAST(ID AS varchar(MAX)) 
           FROM names i 
           WHERE i.Name = n.Name FOR XML PATH(''))
        , 1, 1, '') as IDs
FROM names n
GROUP BY Name
ORDER BY ct DESC

group_concat除非您使用 SQLCLR 选项(我没有这样做的经验),否则最接近您的将是 MSSQL。该STUFF函数负责处理前导逗号。此外,您不想为内部命名,SELECT因为它会将您选择的元素包装在 XML 元素中(别名TD会导致每个元素返回为<TD>value</TD>)。

鉴于上面的输入,这是我得到的结果:

Name    ct  IDs
Mike    3   1,3,5
John    2   0,2
Adam    1   4

编辑:免责声明

&对于可能包含特殊字符(如和号、小于<、大于>和任何数量的其他格式字符)的字符串字段,此技术将无法正常工作。因此,这种技术对简单的整数值最有利,尽管如果您绝对确定没有需要转义的特殊字符,仍然可以将其用于文本。因此,请阅读此处发布的解决方案,以确保正确转义这些字符。

于 2012-08-06T18:06:16.530 回答
1

这是另一种使用递归 CTE 的 SQL Server 方法:

链接到SQLFiddle

; with MyCTE(name,ids, name_id, seq)
as(
    select name, CAST( '' AS VARCHAR(8000) ), -1, 0
    from Data
    group by name
    union all
    select d.name,  
            CAST( ids + CASE WHEN seq = 0 THEN '' ELSE ', ' END + cast(id as varchar) AS VARCHAR(8000) ),
            CAST( id AS int),
            seq + 1
    from MyCTE cte 
    join Data d
        on cte.name = d.name
    where d.id > cte.name_id
)
SELECT name, ids
      FROM ( SELECT name, ids,
                    RANK() OVER ( PARTITION BY name ORDER BY seq DESC )
               FROM MyCTE ) D ( name, ids, rank )
     WHERE rank = 1
于 2012-08-06T19:30:49.497 回答