SQL查询 - 显示计数&所有ID都是同名的

时间:2012-08-06 17:45:00

标签: sql database-design sqlite

我正在尝试显示具有相同名称的表条目数量以及与每个条目相关联的唯一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;

3 个答案:

答案 0 :(得分:2)

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

您可以{/ 3}}使用

答案 1 :(得分: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

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

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

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

编辑:免责声明

此技术不适用于可能包含特殊字符的字符串字段(例如&符号&,小于<,大于>以及任意数量的其他格式字符)。因此,这种技术对于简单的整数值最有用,但如果您绝对确定仍然可以用于文本,则不存在需要转义的特殊字符。因此,请阅读发布的HERE解决方案,以确保正确转义这些字符。

答案 2 :(得分: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