2013-10-14 89 views
1

我有一个字符串从查询返回到另一个表的ID列表。该字符串可以包含1个id或由逗号分隔的id列表。将ID列表转换为其他值

我想从id主表中转换引用其他字段(在本例中为名称)的id列表。

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

您需要一个['INNER JOIN'](http://www.quackit.com/sql/tutorial/sql_inner_join.cfm)。 –

+0

但是,我怎样才能让字符串保持逗号分隔值只显示名称而不是id? – Goolsy

+0

我没有注意到它是一个单一的字符串。 –

回答

0

你碰上的诸多问题一个贮存非规范化和具体而言,分隔数据。关系而言,标准解决方案是创建一个联结表来表示taskjob(例如“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.id列中存在job.name ......您最终将更换两次(或更多)某个东西,因此必须构建一个检查(替换历史字段或临时表,潜在地)。