1. ホーム
  2. sql-server

[解決済み] T-SQLには、文字列を連結するための集約関数がありますか?重複

2023-06-09 04:28:18

質問

重複の可能性があります。

SQL Server 2000 の Implode 型関数?

行の値を結合する T-SQL

私は以下のようなクエリを行っているビューを持っています。

BuildingName    PollNumber
------------    ----------
Foo Centre      12        
Foo Centre      13
Foo Centre      14
Bar Hall        15
Bar Hall        16
Baz School      17

BuildingNamesをグループ化し、PollNumbersのリストを表示するクエリをこのように書きたいのですが。

BuildingName    PollNumbers
------------    -----------
Foo Centre      12, 13, 14
Bar Hall        15, 16
Baz School      17

T-SQLでこれを行うにはどうしたらよいでしょうか。このためにストアドプロシージャを書くのはやりすぎのような気がするので避けたいのですが、私は必ずしもデータベースの専門家ではないので、このようなことはできません。SUM()やAVG()のような集計関数が必要なようですが、T-SQLにそれがあるかどうかはわかりません。私はSQL Server 2005を使用しています。

どのように解決するのですか?

SQL Server 2017 以降で使用する場合。

STRING_AGG()を使用します。

set nocount on;
declare @YourTable table (RowID int, HeaderValue int, ChildValue varchar(5))
insert into @YourTable VALUES (1,1,'CCC')
insert into @YourTable VALUES (2,2,'B<&>B')
insert into @YourTable VALUES (3,2,'AAA')
insert into @YourTable VALUES (4,3,'<br>')
insert into @YourTable VALUES (5,3,'A & Z')
set nocount off
SELECT
    t1.HeaderValue
        ,STUFF(
                   (SELECT
                        ', ' + t2.ChildValue
                        FROM @YourTable t2
                        WHERE t1.HeaderValue=t2.HeaderValue
                        ORDER BY t2.ChildValue
                        FOR XML PATH(''), TYPE
                   ).value('.','varchar(max)')
                   ,1,2, ''
              ) AS ChildValues
    FROM @YourTable t1
    GROUP BY t1.HeaderValue

SELECT
    HeaderValue, STRING_AGG(ChildValue,', ')
    FROM @YourTable
    GROUP BY HeaderValue

OUTPUTです。

HeaderValue 
----------- -------------
1           CCC
2           B<&>B, AAA
3           <br>, A & Z

(3 rows affected)

をSQL Server 2005以降2016までで使用する場合は、以下のようにする必要があります。

--Concatenation with FOR XML and eleminating control/encoded character expansion "& < >"
set nocount on;
declare @YourTable table (RowID int, HeaderValue int, ChildValue varchar(5))
insert into @YourTable VALUES (1,1,'CCC')
insert into @YourTable VALUES (2,2,'B<&>B')
insert into @YourTable VALUES (3,2,'AAA')
insert into @YourTable VALUES (4,3,'<br>')
insert into @YourTable VALUES (5,3,'A & Z')
set nocount off
SELECT
    t1.HeaderValue
        ,STUFF(
                   (SELECT
                        ', ' + t2.ChildValue
                        FROM @YourTable t2
                        WHERE t1.HeaderValue=t2.HeaderValue
                        ORDER BY t2.ChildValue
                        FOR XML PATH(''), TYPE
                   ).value('.','varchar(max)')
                   ,1,2, ''
              ) AS ChildValues
    FROM @YourTable t1
    GROUP BY t1.HeaderValue

OUTPUTです。

HeaderValue ChildValues
----------- -------------------
1           CCC
2           AAA, B<&>B
3           <br>, A & Z

(3 row(s) affected)

また、気をつけなければならないのは、すべての FOR XML PATH の連結が、上記の例のようにXMLの特殊文字を適切に処理するわけではないことに注意してください。