Объединение результатов конкретного запроса SQL в одну строку

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть следующий запрос;

 SELECT custom.name, instance_id 
FROM table1 tb 
WHERE tb.instance_id = 1111 OR tb.instance_id = 2222
  

Это возвращает следующие результаты;

 test, 1111
test1, 1111
test3, 1111
tabletest, 2222
tabletest1, 2222
tabletest2, 2222
  

Я хотел бы иметь возможность сопоставлять instances_id и объединять соответствующие строки в одну строку.

т.е.

 test;test1;test3
tabletest;tabletest1;tabletest2
  

Я могу получить одну строку, но на данный момент это захватывает все результаты и помещает их в одну строку.

 STUFF((
SELECT custom.name   ';'
FROM table1 tb 
WHERE tb.instance_id = 1111 OR tb.instance_id = 222
FOR XML PATH(' '), TYPE.value('.', 'NVARCHAR(MAX)'), 1, 0, ' ')
  

это приводит к

 test;test1;test3;tabletest;tabletest1;tabletest2
  

К сожалению, я не могу обновить последнюю версию sql Server 15, что, возможно, ограничивает меня.

Комментарии:

1. Что вы подразумеваете под «SQL Server версии 15»? Если вы говорите о версии программы — тогда «v15» — это SQL Server 2019 , который является абсолютно новейшей версией, доступной на рынке — конечно, вы не можете обновить эту версию — более новой версии вообще нет!

Ответ №1:

Вам нужно предложение корреляции в подзапросе. Я бы предложил:

 SELECT v.instance_id,
       STUFF((SELECT ';'   tb.name 
              FROM table1 tb 
              WHERE tb.instance_id = v.instance_id
              FOR XML PATH(''), TYPE
             ).value('.', 'NVARCHAR(MAX)'
                    ), 1, 1, ' '
            )
FROM (VALUES (1111), (2222)) v(instance_id);
  

Здесь находится db<>fiddle.

Ответ №2:

Данные

 drop table if exists dbo.tTable;
go
create table dbo.tTable(
  [name]                varchar(100) not null,
  instance_id           int not null);

insert dbo.tTable values
('test',1111),
('test1',1111),
('test3',1111),
('test',2222),
('test1',2222),
('test2',2222);
  

Запрос

 select instance_id, 
      stuff((select ';'   cast([name] as varchar(100))
             from tTable c2
             where t.instance_id = c2.instance_id
             order by [name] FOR XML PATH('')), 1, 1, '') [value1]
from tTable t
group by instance_id;
  

Вывод

 instance_id value1
1111        test;test1;test3
2222        test;test1;test2