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