Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Оптимален начин за конкатенация/обединяване на низове

РЕШЕНИЕ

Определението за оптимално може да варира, но ето как да свържете низове от различни редове, като използвате обикновен Transact SQL, който трябва да работи добре в 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

ОБЯСНЕНИЕ

Подходът се свежда до три стъпки:

  1. Номерирайте редовете с помощта на OVER и PARTITION групирането и подреждането им според нуждите за конкатенацията. Резултатът е Partitioned CTE. Поддържаме броя на редовете във всеки дял, за да филтрираме резултатите по-късно.

  2. Използване на рекурсивен CTE (Concatenated ) итерирайте през номерата на редовете (NameNumber колона) добавяне на Name стойности към FullName колона.

  3. Филтрирайте всички резултати, освен тези с най-висок NameNumber .

Моля, имайте предвид, че за да направите тази заявка предвидима, трябва да дефинирате и двете групи (например във вашия сценарий редове със същия ID са обединени) и сортиране (предполагах, че просто сортирате низа по азбучен ред преди конкатенацията).

Бързо тествах решението на SQL Server 2012 със следните данни:

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

Резултатът от заявката:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Len() срещу datalength() в SQL Server 2005

  2. Разберете към кой дял ще бъде съпоставена дадена стойност в SQL Server (T-SQL)

  3. Изчисляване на разстоянието между две точки (ширина, дължина)

  4. Как да премахнете водещи и последващи знаци в SQL Server

  5. Използване на StringWriter за XML сериализация