sql >> Database teknologi >  >> RDS >> Sqlserver

Optimal måde at sammenkæde/samle strenge

LØSNING

Definitionen af ​​optimal kan variere, men her er, hvordan du sammenkæder strenge fra forskellige rækker ved hjælp af almindelig Transact SQL, som burde fungere fint 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

FORKLARING

Fremgangsmåden koges ned til tre trin:

  1. Nummerer rækkerne med OVER og PARTITION gruppering og bestilling af dem efter behov for sammenkædningen. Resultatet er Partitioned CTE. Vi gemmer tællinger af rækker i hver partition for at filtrere resultaterne senere.

  2. Brug af rekursiv CTE (Concatenated ) gentag rækkenumrene (NameNumber kolonne) ved at tilføje Name værdier til FullName kolonne.

  3. Filtrer alle resultater fra, undtagen dem med det højeste NameNumber .

Husk, at for at gøre denne forespørgsel forudsigelig skal man definere begge grupperinger (f.eks. i dine scenarier rækker med det samme ID er sammenkædet) og sortering (jeg gik ud fra, at du simpelthen sorterer strengen alfabetisk før sammenkædning).

Jeg har hurtigt testet løsningen på SQL Server 2012 med følgende data:

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

Forespørgselsresultatet:

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


  1. Brugerdefineret dato/klokkeslæt formatering i SQL Server

  2. Lagret procedure og tilladelser - er EXECUTE nok?

  3. mysqli_stmt::bind_result():Antallet af bindevariabler matcher ikke antallet af felter i forberedt sætning

  4. Sådan får du flere optællinger med en enkelt forespørgsel i MySQL