T-SQL: агрегируйте «коллекцию» по строке и объединяйте их - PullRequest
0 голосов
/ 05 июня 2019

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

Я пишу отчетный запрос для базы данных, которая уже находится в производстве.Рассмотрим следующую таблицу (аналогично моему текущему набору результатов):

Id     | Code1    | Code2    | Code3    |  Code4   | Code5
-----------------------------------------------------------
1        1          2          3           4         5
1        2          3          4           5         6
2        1          null       null        null      null

Все коды имеют один и тот же «тип», как в буквальном смысле (как типы данных), так и концептуально (как в, они представляют одинаковые«вид» кода, для события такого же типа и т. д.).Очевидно, что эти данные не нормализованы должным образом, но мне все еще нужно преобразовать их.

Я хотел бы написать запрос, который «группирует» по идентификатору и возвращает коллекцию всех уникальных кодов в5 кодовых столбцов.

В конечном счете, моя цель состоит в том, чтобы преобразовать таблицу в:

Id      Codes
1       [1, 2, 3, 4, 5, 6]
2       [1]

(где [], по крайней мере, концептуально представляет какую-то коллекцию, или таблицу, или тип списка)

(На самом деле мне нужно объединиться с этими кодами для быстрого поиска, поэтому «фактический» результат должен выглядеть следующим образом)

Id      CodeStrings
1       [Foo, Bar, Baz, Bon, Fizz, Buzz]
2       [Foo]

Можете ли вы описать шаблон, который позволит мне сформировать "сборник »на ряд и их агрегировать?

Ответы [ 3 ]

1 голос
/ 05 июня 2019

Я бы сначала развернул таблицу, а затем конкатенировал строки, сгруппированные по Id, используя Для пути XML .

1 голос
/ 05 июня 2019

Вам необходимо отключить и повторно объединить. Это довольно просто в SQL Server 2017 +:

select t.id, string_agg(c.code, ',')
from t cross apply
     (select distinct v.code
      from (values (code1), (code2), (code3), (code4), (code5)
           ) v(code)
      where v.code is not null
     ) c;

В более ранних версиях вы можете использовать for xml path:

select t.id, stuff(c.codes, 1, 1, '') as codes
from t cross apply
     (select distinct ',' + v.code
      from (values (code1), (code2), (code3), (code4), (code5)
           ) v(code)
      where v.code is not null
      for xml path ('')
     ) c(codes)
0 голосов
/ 05 июня 2019

Для всего 5 самым простым вариантом может быть:

Select ID, '[' + ISNULL(Code1, '') 
               + ISNULL(' ,' + Code2, '') 
               + ISNULL(' ,' + Code3, '') 
               + ISNULL(' ,' + Code4, '') 
               + ISNULL(' ,' + Code5, '') + ']'
From MyTable

Обратите внимание, что вам может понадобиться обернуть коды в cast или convert до varchar, если они хранятся в виде чисел,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...