I'm using the STRING_AGG function in SQL Server 2017. I'd like to create the same effect as COUNT(DISTINCT <column>)
. I tried STRING_AGG(DISTINCT <column>,',')
but that is not legal syntax.
I'd like to know if there is a T-SQL work-around. Here is my sample:
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
The above produces the following result:
+---------+-----------+--------------+-------------------------+
| State | City | # Of Types | Animals |
+---------+-----------+--------------+-------------------------+
| Arizona | Flagstaff | 1 | dog |
| Florida | Orlando | 2 | dog,bird |
| Arizona | Phoenix | 2 | bird,bird,bird,dog,bird |
+---------+-----------+--------------+-------------------------+
The output is exactly what I want, except I want the concatenated "Animals" listed for Phoenix Arizona to be DISTINCT, like this:
+---------+-----------+--------------+--------------------+
| State | City | # Of Types | Animals |
+---------+-----------+--------------+--------------------+
| Arizona | Flagstaff | 1 | dog |
| Florida | Orlando | 2 | dog,bird |
| Arizona | Phoenix | 2 | bird,dog |
+---------+-----------+--------------+--------------------+
Any ideas?
When I use my real data set, which is much larger, I get an error about the "Animals" column exceeding 8000 characters.
My question I think is the same as this one , except my example is much simpler.
5条答案
按热度按时间idfiyjo81#
Install CLR functions GROUP_CONCAT:
https://github.com/orlando-colamatteo/ms-sql-server-group-concat-sqlclr
then:
ijxebb2r2#
Here is one way to do it.
Since you want the distinct counts as well, it can be done simply by grouping the rows twice. The first
GROUP BY
will remove duplicates, the secondGROUP BY
will produce the final result.Result
If you are still getting an error message about exceeding 8000 characters, then cast the values to
varchar(max)
beforeSTRING_AGG
.Something like
hxzsmxv23#
Here is one more way of doing it (sql fiddle):
You may easily convert the splitting and merging part into a reusable scalar valued function.
NOTE
This is NOT an optimal solution, if you group first and then do aggregate (like answers above) it is better. Also, it does not get
# of Types
, it gets# of Sitings
instead. However, it becomes handy as a quick inline function.yks3o0rb4#
just use
sub-query
http://sqlfiddle.com/#!18/ba4b8/11
xytpbqjk5#
You can use this in postgres. I am not sure about mysql. But this works in postgres.
This will aggregate only distinct values.