sql >> Databasteknik >  >> RDS >> Sqlserver

Optimalt sätt att sammanfoga/sammanfoga strängar

LÖSNING

Definitionen av optimal kan variera, men så här sammanfogar du strängar från olika rader med vanlig Transact SQL, vilket borde fungera bra i 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

FÖRKLARING

Tillvägagångssättet kokar ner till tre steg:

  1. Numrera raderna med OVER och PARTITION gruppera och beställa dem efter behov för sammanlänkningen. Resultatet är Partitioned CTE. Vi behåller antalet rader i varje partition för att filtrera resultaten senare.

  2. Använder rekursiv CTE (Concatenated ) iterera genom radnumren (NameNumber kolumn) lägga till Name värden till FullName kolumn.

  3. Filtrera bort alla resultat utom de med högst NameNumber .

Tänk på att för att göra denna fråga förutsägbar måste man definiera båda grupperingarna (till exempel i dina scenariorader med samma ID är sammanlänkade) och sortering (jag antog att du helt enkelt sorterar strängen alfabetiskt före sammanlänkning).

Jag har snabbt testat lösningen på SQL Server 2012 med följande data:

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

Frågeresultatet:

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


  1. Återställa en ackumulerad summa?

  2. Hur använder man Array/Table Parameter till Oracle (ODP.NET 10g) via ADO.NET/C#?

  3. Hur man delar en sträng i SQL Server

  4. 1114 (HY000):Bordet är fullt