我从查询返回一个字符串,该字符串将id列表返回给另一个表。该字符串可以包含1个id或由逗号分隔的ID列表。
我想转换id列表,以便从ids主表中引用另一个字段(在本例中为名称)。
E.g。 select * from task
返回:
taskid,jobid,start,finish
1,"333",09:00,12:00
2,"334",08:00,16:00
3,"333,334",09:00,17:00
我希望引用“job
”表格,以便在字符串中返回“job.name
”代替job.jobid
。所以它看起来像这样:
taskid,jobid,start,finish
1,"Wash",09:00,12:00
2,"Dry",08:00,16:00
3,"Wash,Dry",09:00,17:00
答案 0 :(得分:0)
您遇到了存储非规范化,特别是分隔数据的众多问题之一。从关系上讲,标准解决方案是创建一个联结表来表示task
和job
之间的这种多对多关系(例如“JobToTask”)。
但是,如果你无法改变目前的情况,一种方法是循环你的集合并一次迭代一次:
-- Create a temporary spot for id replacements
declare @output table (
taskid int, jobnamelist varchar(1000)
)
insert into @output select taskid, ',' + jobid + ',' from task
-- Run replacements
while exists (select null from @output t join job j on t.jobnamelist like '%,' + cast(j.jobid as varchar(50)) + ',%') begin
update t
set jobnamelist = replace(
jobnamelist,
',' + (select cast(min(jobid) as varchar(11)) from job where t.jobnamelist like '%,' + cast(jobid as varchar(50)) + ',%') + ',',
',' + (select name from job where jobid = (select min(jobid) from job where t.jobnamelist like '%,' + cast(jobid as varchar(50)) + ',%')) + ','
)
from @output t
where exists (select null from job where t.jobnamelist like '%,' + cast(jobid as varchar(50)) + ',%')
end
-- Get final output
select taskid, substring(jobnamelist, 2, len(jobnamelist) - 2) as jobnamelist
from @output
-- taskid jobnamelist
-- ------ -----------
-- 1 Wash
-- 2 Dry
-- 3 Wash,Dry
特别注意在找到或进行替换时,将分隔符添加到字符串的两端。这可以防止您更换部分ID(例如33在334中)。
如果必须在单个select语句中执行此操作,则可以使用recursive CTE运行类似的逻辑。
要考虑的一个问题是,如果job.name
列中存在job.id
,那么您最终会更换两次(或更多)内容并因此需要内置检查(可能是替换历史字段或临时表)。