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
출력:
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
출력:
HeaderValue ChildValues
----------- -------------------
1 CCC
2 AAA, B<&>B
3 <br>, A & Z
(3 row(s) affected)
그리고 조심해요, 다는 아니에요.FOR XML PATH
연결은 위의 예시와 같이 XML 특수문자를 적절하게 처리합니다.
SQL Server에는 기본 제공 함수가 없지만 사용자 정의 집계를 작성하여 수행할 수 있습니다.이 문서에서는 SQL Server 샘플의 일부로서 다음과 같은 기능에 대해 설명합니다.http://msdn.microsoft.com/en-us/library/ms182741.aspx
예를 들어 Concatenate Aggregate의 코드를 포함합니다.사용하려면 Visual Studio에서 데이터베이스 프로젝트를 만들고 새 SqlAggregate를 추가한 후 아래 샘플로 코드를 바꿉니다.도입이 완료되면 데이터베이스에서 새로운 어셈블리와 집약 함수를 찾을 수 있습니다.Concatenate
using System;
using System.Data.SqlTypes;
using System.IO;
using System.Text;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToNulls = true, IsInvariantToDuplicates = false, IsInvariantToOrder = false, MaxByteSize = 8000, Name = "Concatenate")]
public class Concatenate : IBinarySerialize
{
private StringBuilder _intermediateResult;
internal string IntermediateResult {
get
{
return _intermediateResult.ToString();
}
}
public void Init()
{
_intermediateResult = new StringBuilder();
}
public void Accumulate(SqlString value)
{
if (value.IsNull) return;
_intermediateResult.Append(value.Value);
}
public void Merge(Concatenate other)
{
if (null == other)
return;
_intermediateResult.Append(other._intermediateResult);
}
public SqlString Terminate()
{
var output = string.Empty;
if (_intermediateResult != null && _intermediateResult.Length > 0)
output = _intermediateResult.ToString(0, _intermediateResult.Length - 1);
return new SqlString(output);
}
public void Read(BinaryReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
_intermediateResult = new StringBuilder(reader.ReadString());
}
public void Write(BinaryWriter writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
writer.Write(_intermediateResult.ToString());
}
}
이를 사용하려면 집약 쿼리를 작성하기만 하면 됩니다.
create table test(
id int identity(1,1) not null
primary key
, class tinyint not null
, name nvarchar(120) not null )
insert into test values
(1, N'This'),
(1, N'is'),
(1, N'just'),
(1, N'a'),
(1, N'test'),
(2, N','),
(3, N'do'),
(3, N'not'),
(3, N'be'),
(3, N'alarmed'),
(3, N','),
(3, N'this'),
(3, N'is'),
(3, N'just'),
(3, N'a'),
(3, N'test')
select dbo.Concatenate(name + ' ')
from test
group by class
drop table test
쿼리의 출력은 다음과 같습니다.
-- Output
-- ===================
-- This is just a test
-- ,
-- do not be alarmed , this is just a test
클래스 및 집계를 스크립트로 패키징했습니다.이 스크립트는 https://gist.github.com/FilipDeVos/5b7b4addea1812067b09 에서 찾을 수 있습니다.
언급URL : https://stackoverflow.com/questions/5031204/does-t-sql-have-an-aggregate-function-to-concatenate-strings
'programing' 카테고리의 다른 글
비동기 코드에서 비동기 메서드를 호출합니다. (0) | 2023.04.23 |
---|---|
VBA를 사용하지 않고 Excel에서 역문자열 검색을 실행하는 방법은 무엇입니까? (0) | 2023.04.23 |
iOS에서 이메일 주소가 유효한지 확인합니다. (0) | 2023.04.23 |
Swift에서 UITextView에 자리 표시자 텍스트를 추가하시겠습니까? (0) | 2023.04.23 |
가장 일반적인 SQL 안티 패턴은 무엇입니까? (0) | 2023.04.23 |