看起来您正在要求两个单独的查询,一个是使用ProcessID
列中的非规范化数据来解决您的原始表,然后是第二个查询(如果tblFlow
数据是规范化的)。
tblFlow 非规范化查询
如果您无法规范化tblFlow
表中的数据,这意味着您将数据存储在列表中,并用破折号 ( PID01-PID02-PID03
) 分隔。然后我将按照以下方式进行。
首先,我将创建一个拆分字符串用户定义的函数,它将ProcessId
字符串分成多个列。网上有很多功能,但这是我通常使用的功能:
CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))
returns @temptable TABLE (items varchar(MAX))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end;
一旦你创建了函数。然后你会查询使用CROSS APPLY
将processId
列表传递给函数。查询将是:
;with cte as
(
select f.flowid, f.flowname, f.processid, s.items processItem
from tblFlow f
cross apply dbo.Split(f.processid, '-') s
)
select *
from cte;
请参阅SQL Fiddle with Demo。这给出了一个结果:
| FLOWID | FLOWNAME | PROCESSID | PROCESSITEM |
-------------------------------------------------------
| F00 | Flow1 | PID01-PID02-PID03 | PID01 |
| F00 | Flow1 | PID01-PID02-PID03 | PID02 |
| F00 | Flow1 | PID01-PID02-PID03 | PID03 |
| F01 | Flow2 | PID01-PID03-PID02 | PID01 |
| F01 | Flow2 | PID01-PID03-PID02 | PID03 |
| F01 | Flow2 | PID01-PID03-PID02 | PID02 |
将ProcessItem
数据拆分为行后,您就可以轻松地连接到现有表并生成新的ProcessNames
. 要创建串联列表,您可以使用FOR XML PATH
和 STUFF。查询将是:
;with cte as
(
select f.flowid, f.flowname, f.processid, s.items processItem
from tblFlow f
cross apply dbo.Split(f.processid, '-') s
)
select distinct c.flowid,
c.flowname,
c.processid,
STUFF(
(SELECT '-' + p.ProcessName
FROM cte c2
inner join tblProcess p
on c2.processItem = p.processId
where c.flowid = c2.flowid
FOR XML PATH (''))
, 1, 1, '') AS ProcessName
from cte c;
请参阅SQL Fiddle with Demo。这给出了一个结果:
| FLOWID | FLOWNAME | PROCESSID | PROCESSNAME |
----------------------------------------------------------------------
| F00 | Flow1 | PID01-PID02-PID03 | Process1-Process2-Process3 |
| F01 | Flow2 | PID01-PID03-PID02 | Process1-Process2-Process3 |
标准化 tblFlow
现在,如果tblFlow
数据已经规范化并且您想要创建两个连接列表,一个带有processId
,另一个带有processName
,那么您可以使用以下内容:
select distinct f.flowid,
f.flowname,
STUFF(
(SELECT '-' + f1.Processid
FROM tblFlow f1
where f.flowid = f1.flowid
FOR XML PATH (''))
, 1, 1, '') AS Processid,
STUFF(
(SELECT '-' + p.ProcessName
FROM tblFlow f1
inner join tblProcess p
on f1.ProcessId = p.ProcessId
where f.flowid = f1.flowid
FOR XML PATH (''))
, 1, 1, '') AS ProcessName
from tblFlow f;
请参阅SQL Fiddle with Demo。这会产生一个结果:
| FLOWID | FLOWNAME | PROCESSID | PROCESSNAME |
----------------------------------------------------------------------
| F00 | Flow1 | PID01-PID02-PID03 | Process1-Process2-Process3 |
| F01 | Flow2 | PID01-PID03-PID02 | Process1-Process2-Process3 |