Как разрешить значения, разделенные запятыми, на основе набора? - PullRequest
0 голосов
/ 01 октября 2019

У меня есть главная таблица, которая содержит коды, разделенные запятыми для каждого идентификатора:

create table main (id int, codes nvarchar(3))

id  codes
1   HIR, RES, NAS
2   TA1, WQ9, PLM

И справочная таблица, которая описывает, что означают эти коды:

create table lookup (code nvarchar(3), description nvarchar(100))

code  description
HIR   High Rise
NAS   Mobile Home
PLM   Proposed Attached
...

Я хочу выбрать из основной таблицы и заменить разделенный запятыми список кодов разделенными запятыми списками соответствующих описаний:

id  codes
1   High Rise, Residential, Mobile Home

Iразобрался, как проходить через каждую строку, разбивать CSV, запрашивать каждую вручную, создавать строку обратно и производить то, что я хочу.

Однако есть ли способ сделать это на основе множеств (и быстрее)?

Ответы [ 3 ]

2 голосов
/ 01 октября 2019

Поскольку вы находитесь в 2016 году, одним из вариантов будет string_split, но нет gtd для поддержания последовательности. Возможно, это поможет

Пример

Select A.ID
      ,Codes = B.S
 From  Main A
 Cross Apply (
                Select S = stuff((Select ', ' +[description] 
                                   From (
                                          Select RetSeq = Row_Number() over (Order By (Select null))
                                                ,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(100)')))
                                           From  (Select x = Cast('<x>' + replace((Select replace(A.[codes],',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
                                           Cross Apply x.nodes('x') AS B(i)
                                         ) B1
                                    Join Lookup B2 on B1.RetVal=B2.code
                                    Order by RetSeq
                                    For XML Path (''))
                                  ,1,2,'') 
             ) B

Возвраты

ID  Codes
1   High Rise, Mobile Home
2   Proposed Attached

Примечание Элементы отсутствуют, поскольку поиск не был завершен,

2 голосов
/ 01 октября 2019

Поскольку вы можете использовать SQL Server 2017, существует STRING_AGG():

select m.id, string_agg(l.description, ', ') within group (order by charindex(l.code, m.codes)) codes
from main m inner join lookup l
on concat(',', replace(m.codes, ', ', ','), ',') like concat('%', l.code, '%')
group by m.id

См. Демонстрационную версию . Результаты:

> id | codes                              
> -: | :----------------------------------
>  1 | High Rise, Residential, Mobile Home
1 голос
/ 01 октября 2019

Для основной таблицы, которую вы хотите сделать кросс, примените STRING_SPLIT, затем вы можете присоединить его к вашей таблице поиска и использовать метод stuff () для xml

. Вы можете узнать о кросс-применении STRING_SPLIT. (SS 2016) здесь: Превращение строки, разделенной запятыми, в отдельные строки (другие методы перечислены)

Вы можете узнать о материале с помощью for xml здесь: Преобразовать несколько строк водин с запятой в качестве разделителя

...