sql >> Database >  >> RDS >> Sqlserver

Optimale manier om strings samen te voegen/te aggregeren

OPLOSSING

De definitie van optimaal kan variëren, maar hier leest u hoe u tekenreeksen uit verschillende rijen samenvoegt met gewone Transact SQL, wat prima zou moeten werken in Azure.

;WITH Partitioned AS
(
    SELECT 
        ID,
        Name,
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Name) AS NameNumber,
        COUNT(*) OVER (PARTITION BY ID) AS NameCount
    FROM dbo.SourceTable
),
Concatenated AS
(
    SELECT 
        ID, 
        CAST(Name AS nvarchar) AS FullName, 
        Name, 
        NameNumber, 
        NameCount 
    FROM Partitioned 
    WHERE NameNumber = 1

    UNION ALL

    SELECT 
        P.ID, 
        CAST(C.FullName + ', ' + P.Name AS nvarchar), 
        P.Name, 
        P.NameNumber, 
        P.NameCount
    FROM Partitioned AS P
        INNER JOIN Concatenated AS C 
                ON P.ID = C.ID 
                AND P.NameNumber = C.NameNumber + 1
)
SELECT 
    ID,
    FullName
FROM Concatenated
WHERE NameNumber = NameCount

UITLEG

De aanpak komt neer op drie stappen:

  1. Nummer de rijen met OVER en PARTITION groeperen en ordenen zoals nodig is voor de aaneenschakeling. Het resultaat is Partitioned CTE. We houden het aantal rijen in elke partitie bij om de resultaten later te filteren.

  2. Recursieve CTE gebruiken (Concatenated ) doorloop de rijnummers (NameNumber kolom) toevoegen van Name waarden naar FullName kolom.

  3. Filter alle resultaten behalve die met het hoogste NameNumber .

Houd er rekening mee dat om deze zoekopdracht voorspelbaar te maken, u beide groepen moet definiëren (bijvoorbeeld in uw scenariorijen met dezelfde ID zijn aaneengeschakeld) en sorteren (ik nam aan dat je de tekenreeks eenvoudig alfabetisch sorteert voordat je ze aaneenschakelt).

Ik heb de oplossing snel getest op SQL Server 2012 met de volgende gegevens:

INSERT dbo.SourceTable (ID, Name)
VALUES 
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')

Het resultaat van de zoekopdracht:

ID          FullName
----------- ------------------------------
2           Stylus
3           Bar, Baz, Foo
1           Matt, Rocks


  1. Hoe DATE() werkt in MariaDB

  2. Tel cumulatief totaal in Postgresql

  3. .NET op Linux verbinden met een ODBC-gegevensbron

  4. Hoe kom je aan het einde van een dag?