SQL Server: использовать CTE в качестве подзапроса для сжатия строк в объединенную строку - PullRequest
0 голосов
/ 03 января 2019

Я переписываю несколько страниц плохо написанного приложения, я пытаюсь включить эту логику в основной запрос как подзапрос, чтобы я мог получить все данные одним махом вместо соединения 50K раз, как текущий код.

Я начал с

DECLARE @combinedString NVARCHAR(MAX),@mds   NVARCHAR(MAX)

SELECT 
    @combinedString = COALESCE(@combinedString + ', ', '') + serial,
    @mds = MDS  
FROM 
    (aircraftserials 
LEFT JOIN  
    serialnums ON serialnums.ID = aircraftserials.Serialnum_ID) 
WHERE 
    (85 = aircraftserials.Aircraft_ID AND serial IS NOT NULL)

Я хочу исключить эти переменные и сделать это подзапросом,

Я думаю, что мне нужен CTE;конечный результат должен быть

MDS, concatenated serials

Я пробовал этот пост, но не могу его получить Упростить объединение строк CTE?

Вот пример данных

CREATE TABLE TestBed 
(
     Aircraft_ID INT, 
     Serial VARCHAR(50),
     MDS VARCHAR(50)
)

INSERT INTO TestBed (Aircraft_ID, Serial, MDS) 
VALUES (85, '56-1965', 'T-37B'),
       (85, '56-1967', 'T-37B'),
       (85, '56-3547', 'T-37B'),
       (85, '56-3577', 'T-37B'),
       (85, '57-2265', 'T-37B'),
       (85, '57-2272', 'T-37B'),
       (85, '58-1915', 'T-37B'),
       (85, '58-1925', 'T-37B'),
       (85, '59-0249', 'T-37B'),
       (85, '59-0273', 'T-37B'),
       (85, '59-0299', 'T-37B')

select * from TestBed

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Я придумал рекурсивный CTE на основе ваших тестовых данных

;with ForceId as 
    (SELECT ROW_NUMBER() OVER(partition by MDS order by serial) as RN,* FROM TestBed),
    RECURS as
    (SELECT f.MDS,f.RN,f.Serial, cast(f.serial as nvarchar(max)) as x  FROM ForceId F WHERE F.RN = 1
     UNION ALL
     SELECT f2.mds,f2.rn, r.Serial,r.x  + ', ' + f2.Serial  FROM ForceId F2 
                    JOIN RECURS R
                    ON F2.mds = R.mds 
                    AND R.RN + 1 = F2.rn        
    )
    SELECT MDS, x  FROM 
            recurs r where r.rn = 
            (select max(r2.rn) from recurs r2 where r.MDS = r2.mds)
0 голосов
/ 03 января 2019

Я думаю, что вы ищете не CTE, а агрегат с конкатенацией строк. В SQL Server это можно сделать с помощью подзапроса FOR XML.

SELECT tb1.aircraft_id,
       stuff((SELECT concat(', ', tb2.serial)
              FROM testbed tb2
              WHERE tb2.aircraft_id = tb1.aircraft_id
                    AND tb2.mds = tb1.mds
              FOR XML PATH ('')), 1, 2, '') serial,
       tb1.mds
       FROM testbed tb1
       GROUP BY tb1.aircraft_id,
                tb1.mds;

дб <> скрипка

Кстати: если mds всегда одинаково для каждого самолета, то оно должно быть не в testbed, а в таблице самолетов.

...