Динамически использовать данные из 1 таблицы в другую

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть одна таблица category_code, имеющая такие данные, как

 SELECT Item, Code, Prefix from category_codes
    Item         Code  Prefix
    Bangles      BL    BL
    Chains       CH    CH
    Ear rings    ER    ER
    Sets         Set   ST
    Rings        RING  RG
    Yellow GOld  YG    YG........
  

У меня есть другая таблица item_categories, содержащая такие данные, как

 select code,name  from item_categories
code            name
AQ.TM.PN        AQ.TM.PN
BL.YG.CH.ME.PN  BL.YG.CH.ME.PN
BS.CZ.ST.YG.PN  BS.CZ.ST.YG.PN
CR.YG           CR.YG.......
  

я хочу обновить item_categories.name столбец, соответствующий столбцу category_code.item, подобный

 code               name
BL.YG.CH.ME.PN     Bangles.Yellow Gold.Chains.. . . . 
  

Пожалуйста, предложите хорошее решение для этого. Заранее спасибо.

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

1. Ваша проблема в том, что ваша модель данных ошибочна. В вашей первой таблице отображаются элементы с их кодами. Однако ваша вторая таблица показывает строки с комбинациями кодов, но ничто не гарантирует, что эти строки правильно отформатированы или что все коды в строке являются допустимыми кодами. Вместо этого у вас должна быть таблица с одной строкой на комбинацию и кодом. Это гарантировало бы согласованность данных, и вы можете STRING_AGG легко получить объединенные коды и объединенные имена.

Ответ №1:

Сначала разделите код на несколько строк, объедините с кодом категории, а затем объедините результат для обновления таблицы.

Вот пример, основанный на данных, которые вы предоставили

 create table #category_code (item varchar(max), code varchar(max), prefix varchar(max));
create table #item_categories (code varchar(max), name varchar(max));
    
insert into #category_code (item, code, prefix) values ('Bangles','BL','BL'),('Chains','CH','CH'),('Ear rings','ER','ER'), ('Sets','Set','ST'),('Rings','RING','RG'), ('Yellow gold','YG','YG');    
insert into #item_categories (code, name) values ('AQ.TM,PN','AQ.TM.PN'),('BL.YG.CH.ME.PN','BL.YG.CH.ME.PN'),('BS.CZ.ST.YG.PN','BS.CZ.ST.YG.PN')

 
;with splitted as (  -- split the codes into individual code
    select row_number() over  (partition by ic.code order by ic.code)  as id, ic.code, x.value, cc.item
    from #item_categories ic
    outer apply string_split(ic.code, '.') x   -- SQL Server 2016 , otherwise, use another method to split the data
    left join #category_code cc on cc.code = x.value -- some values are missing in you example, but can use an inner join
)

, joined as ( -- then joined them to concat the name
    select id, convert(varchar(max),code) as code, convert(varchar(max),coalesce(item   ',','')) as Item
    from splitted
    where id = 1
    union all
    select s.id, convert(varchar(max), s.code),  convert(varchar(max), j.item    coalesce(s.item   ',',''))
    from splitted s
    inner join joined j on j.id = s.id - 1 and j.code = s.code 
)
update #item_categories 
    set name = substring (j.item ,1,case when len(j.item) > 1 then len(j.item)-1 else 0 end)
output deleted.name, inserted.name
from #item_categories i
inner join joined j on j.code = i.code
inner join (select code, max(id)maxid from joined group by code) mj on mj.code = j.code and mj.maxid = j.id