WITH CTE 和大型 UNION 查询的替代方法

Alternate approach to WITH CTE and large UNION query

我想修改我收到的剧本。

它目前的工作方式是通过使用大量 UNION 的 WITH CTE。

当前设置

我们从源 table 获取一条记录,使用 [Name] A 将其插入目标 table 一次,然后使用 [Name] B 再次插入它。本质上是创建多行在目的地,尽管 [Name].

不同

一个事务的示例是从 [Source] 中获取此行:

ID [123] Name [Red and Green]

我目前在[Destination]设置的结果是:

ID [123] Name [Red]
ID [123] Name [Green]

当前逻辑

这是当前逻辑的简化版本:

WITH CTE
AS  
             
(SELECT ID, 
'Red' AS [Name]
FROM [Source_Table]
WHERE [Name] = 'Red and Green'

UNION ALL
              
SELECT ID, 
'Green' AS [Name] 
FROM [Source_Table]
WHERE [Name] = 'Red and Green')


INSERT INTO [Destination_Table]  
(ID, 
[Name])
SELECT ID, 
[Name]
FROM CTE; 

我想返工的原因是当我们得到一个新的 [Name] 时,我们必须手动将另一部分代码添加到我们的(不断增加的)UNION 中,以确保它被拾取。

我考虑过的

我考虑的是在控件 table 之外设置一个 WHILE LOOP(或 CURSOR)运行,我们可以在其中存储所有 [Names]。但是,我不确定这是否是最好的方法,而且我还不太熟悉 LOOPS/CURSORS。此外,一旦所有 [Name] 完成,我也不太确定如何停止循环。

非常感谢任何帮助。

引入一个名为 Color_List 的新 table,其中每种可能的颜色只包含一行。然后这样做:

with cte as
(
    select
        st.ID,
        c.colorname
    from
        Source_Table s
    inner join
        Color_List c
    on
        CHARINDEX(c.colorname, s.[Name]) > 0
)

insert into Destination_Table
(
    ID,
    [Name]
)
select
    ID,
    colorname
from
    cte

此方法的好处是您 hard-coding 查询中没有任何颜色名称。 Color_List table.

中维护所有颜色名称(并且可能有两个以上的颜色名称)

您可以使用 cross apply 来复制行:

insert into [destination_table]  (id, name)
select x.*
from source_table s
cross apply (values (id, 'Red'), (id, 'Green')) x(id, name)
where name = 'Red and Green'

您可以使用 string_split 将值分开。首先用竖线“|”替换“和”。然后在垂直管道上做一个字符串拆分。

drop table if exists #tTEST;
go
select * INTO #tTEST from (values 
(1, '[123]', 'Name', '[Red and Green]')) V(ID, testCol, nameCol, stringCol);

select ID, testCol, nameCol, 
       case when left([value], 1)!='[' then concat('[',[value]) else 
        case when right([value], 1)!=']' then concat([value], ']') else [value] end end valCol
from #tTEST t
     cross apply string_split(replace(t.stringCol, ' and ', '|'), '|');

结果

ID  testCol nameCol valCol
1   [123]   Name    [Red]
1   [123]   Name    [Green]