我正在SQL Server 2017中使用STRING_AGG函数。我想创建与COUNT(DISTINCT <column>)
相同的效果。我尝试过STRING_AGG(DISTINCT <column>,',')
,但这不是合法的语法。
我想知道是否有T-SQL解决方法。这是我的示例:
WITH Sitings
AS
(
SELECT * FROM (VALUES
(1, 'Florida', 'Orlando', 'bird'),
(2, 'Florida', 'Orlando', 'dog'),
(3, 'Arizona', 'Phoenix', 'bird'),
(4, 'Arizona', 'Phoenix', 'dog'),
(5, 'Arizona', 'Phoenix', 'bird'),
(6, 'Arizona', 'Phoenix', 'bird'),
(7, 'Arizona', 'Phoenix', 'bird'),
(8, 'Arizona', 'Flagstaff', 'dog')
) F (ID, State, City, Siting)
)
SELECT State, City, COUNT(DISTINCT Siting) [# Of Types], STRING_AGG(Siting,',') Animals
FROM Sitings
GROUP BY State, City
上面的结果如下:
+---------+-----------+--------------+-------------------------+
| State | City | # Of Types | Animals |
+---------+-----------+--------------+-------------------------+
| Arizona | Flagstaff | 1 | dog |
| Florida | Orlando | 2 | dog,bird |
| Arizona | Phoenix | 2 | bird,bird,bird,dog,bird |
+---------+-----------+--------------+-------------------------+
输出正是我想要的,除了我希望为Phoenix Phoenix列出的级联“动物”是DISTINCT,例如:
+---------+-----------+--------------+--------------------+
| State | City | # Of Types | Animals |
+---------+-----------+--------------+--------------------+
| Arizona | Flagstaff | 1 | dog |
| Florida | Orlando | 2 | dog,bird |
| Arizona | Phoenix | 2 | bird,dog |
+---------+-----------+--------------+--------------------+
有什么想法吗?
使用更大的真实数据集时,出现“ Animals”列超过8000个字符的错误。
我认为我的问题与this one相同,只是我的示例更简单。
答案 0 :(得分:2)
这是一种方法。
由于您还希望获得不同的计数,因此只需将行分组两次即可完成。第一个GROUP BY
将删除重复项,第二个GROUP BY
将产生最终结果。
WITH
Sitings
AS
(
SELECT * FROM (VALUES
(1, 'Florida', 'Orlando', 'bird'),
(2, 'Florida', 'Orlando', 'dog'),
(3, 'Arizona', 'Phoenix', 'bird'),
(4, 'Arizona', 'Phoenix', 'dog'),
(5, 'Arizona', 'Phoenix', 'bird'),
(6, 'Arizona', 'Phoenix', 'bird'),
(7, 'Arizona', 'Phoenix', 'bird'),
(8, 'Arizona', 'Flagstaff', 'dog')
) F (ID, State, City, Siting)
)
,CTE_Animals
AS
(
SELECT
State, City, Siting
FROM Sitings
GROUP BY State, City, Siting
)
SELECT
State, City, COUNT(1) AS [# Of Sitings], STRING_AGG(Siting,',') AS Animals
FROM CTE_Animals
GROUP BY State, City
ORDER BY
State
,City
;
结果
+---------+-----------+--------------+----------+
| State | City | # Of Sitings | Animals |
+---------+-----------+--------------+----------+
| Arizona | Flagstaff | 1 | dog |
| Arizona | Phoenix | 2 | bird,dog |
| Florida | Orlando | 2 | bird,dog |
+---------+-----------+--------------+----------+
如果仍然收到超过8000个字符的错误消息,则将值强制转换为varchar(max)
之前的STRING_AGG
。
类似
STRING_AGG(CAST(Siting AS varchar(max)),',') AS Animals
答案 1 :(得分:1)
只需使用sub-query
WITH Sitings
AS
(
SELECT * FROM (VALUES
(1, 'Florida', 'Orlando', 'bird'),
(2, 'Florida', 'Orlando', 'dog'),
(3, 'Arizona', 'Phoenix', 'bird'),
(4, 'Arizona', 'Phoenix', 'dog'),
(5, 'Arizona', 'Phoenix', 'bird'),
(6, 'Arizona', 'Phoenix', 'bird'),
(7, 'Arizona', 'Phoenix', 'bird'),
(8, 'Arizona', 'Flagstaff', 'dog')
) F (ID, State, City, Siting)
)
select State,City,count(*) as [# Of Types],STRING_AGG(Siting,',') AS Animals from
(
SELECT State, City, Siting
FROM Sitings
GROUP BY State, City,Siting
) as T group by State,City
http://sqlfiddle.com/#!18/ba4b8/11
State City # Of Types Animals
Arizona Flagstaff 1 dog
Florida Orlando 2 bird,dog
Arizona Phoenix 2 bird,dog
答案 2 :(得分:1)
当然答复很晚。
这是另一种方式。可以对STRING_AGG(Siting,',')
中的选址进行子查询以返回DISTINCT的SITTING列表,其中分组键与STATE和CITIES匹配。
WITH Sitings
AS
(
SELECT * FROM (VALUES
(1, 'Florida', 'Orlando', 'bird'),
(2, 'Florida', 'Orlando', 'dog'),
(3, 'Arizona', 'Phoenix', 'bird'),
(4, 'Arizona', 'Phoenix', 'dog'),
(5, 'Arizona', 'Phoenix', 'bird'),
(6, 'Arizona', 'Phoenix', 'bird'),
(7, 'Arizona', 'Phoenix', 'bird'),
(8, 'Arizona', 'Flagstaff', 'dog')
) F (ID, State, City, Siting)
)
SELECT
S.State,
S.City,
COUNT(DISTINCT S.Siting) AS [# Of Types],
--STRING_AGG(S.Siting,',') AS Animals
(
SELECT STRING_AGG(U.SITING, ',')
FROM
(
SELECT DISTINCT T.Siting
FROM Sitings AS T
WHERE
T.State = S.State AND
T.City = S.City
) AS U
) AS ANIMAL
FROM
Sitings AS S
GROUP BY
S.State,
S.City
ORDER BY
S.State,
S.City
答案 3 :(得分:1)
这是另一种实现方法(sql fiddle):
WITH Sitings
AS
(
SELECT * FROM (VALUES
(1, 'Florida', 'Orlando', 'bird'),
(2, 'Florida', 'Orlando', 'dog'),
(3, 'Arizona', 'Phoenix', 'bird'),
(4, 'Arizona', 'Phoenix', 'dog'),
(5, 'Arizona', 'Phoenix', 'bird'),
(6, 'Arizona', 'Phoenix', 'bird'),
(7, 'Arizona', 'Phoenix', 'bird'),
(8, 'Arizona', 'Flagstaff', 'dog')
) F (ID, State, City, Siting)
)
select State,City,count(*) as [# Of Types],(select string_agg(value,', ') from (select distinct value from string_split(string_agg(Siting, ','),',')) t) AS Animals
FROM Sitings
GROUP BY State, City
您可以轻松地将拆分和合并部分转换为可重用的标量值函数。
欢迎专家对性能发表评论。