2017-04-25 116 views
0

我有這樣一個表:SQL服務器

Rule | Mask  |Replacement 
--------------------------------- 
@ # 12 | @   |[^0-9] 
@ # 12 | #   |[0-9] 

即我構造接合這兩個表

表1

Mask_ID | Mask  |Replacement 
--------------------------------- 
1  | @   |[^0-9] 
2  | #   |[0-9] 

表2

Rule_ID | Rule 
-------------- 
1  | @ # 12 

我想結果是這樣的:

Rule | Expression 
-------------------- 
@ # 12 | [^0-9] [0-9] 12 

我一直在試圖使用替換按鈕要做到這一點,但我只能夠產生這樣的結果

Rule | Expression 
-------------------- 
@ # 12 | [^0-9] # 12 
@ # 12 | @ [0-9] 12 

我不知道如何讓REPLACE函數將多行應用於單行。如果有人有任何建議,我將不勝感激。

這是我到目前爲止,但它使我得到我上面提到的結果:

SELECT 
    A.PointMask_CODE 
    ,B.PointMasking_Rule_CODE 
    ,B.Mask 
    ,B.Escape_Character 
    ,B.EscapedMaskRule 
    ,REPLACE(A.PointMask_CODE, B.Mask, B.EscapedMaskRule) 
FROM 
tblStatusPointMasks_CORE A 
LEFT JOIN 
vwAORs_Status_PointMasks_EscapedRules B 
ON 
PointMask_CODE LIKE '%' + B.EscapedMask + '%' ESCAPE ISNULL(B.Escape_Character, '\') 

enter image description here

+0

這不是一個關係設計。這就是爲什麼你有這麼多麻煩。您在Rule列中嵌入數組/符號列表,然後嘗試將其投影到表連接中。將數組和列表嵌入列中違反了第一範式。 – RBarryYoung

回答

3

了給定的樣本數據,你可以使用遞歸common table expression (cte)

create table masks (mask_id int, mask varchar(32), replacement varchar(32)); 
insert into masks values 
(1, '@', '[^0-9]') 
,(2, '#', '[0-9]'); 

create table rules (rule_id int, rule_txt varchar(32)); 
insert into rules values 
(1, '@ # 12'); 

with cte as (
    select 
     r.rule_id 
    , r.rule_txt 
    , masks = 0 
    from rules r 
    union all 
    select 
     r.rule_id 
    , rule_txt = convert(varchar(32),replace(r.rule_txt,m.mask,m.replacement)) 
    , masks = r.masks+1 
    from masks m 
    inner join cte r 
     on r.rule_txt like '%'+m.mask+'%' 
) 
select top 1 * 
from cte 
order by masks desc 

rextester演示:http://rextester.com/KAV58392

回報:

+---------+-----------------+-------+ 
| rule_id | rule_txt  | masks | 
+---------+-----------------+-------+ 
|  1 | [^0-9] [0-9] 12 |  2 | 
+---------+-----------------+-------+ 
0

還有一個選項,使用字符串操作...

create table masks (mask_id int, mask varchar(32), replacement varchar(32)); 
insert into masks values 
(1, '@', '[^0-9]') 
,(2, '#', '[0-9]'); 

create table rules (rule_id int, rule_txt varchar(32)); 
insert into rules values 
(1, '@ # @ # 12'); 

declare @Table Table (charval varchar(10)) 
declare @char varchar(10), @rule_txt varchar(50) 
select @rule_txt=rule_txt FROM rules 
while charindex(' ',@rule_txt)>0 
begin 
    select @char=substring(@rule_txt,1,charindex(' ',@rule_txt)-1) 
    FROM rules 
    insert into @Table values (@char) 
    SET @rule_txt=RIGHT(@rule_txt,(len(@rule_txt)-charindex(' ',@rule_txt))) 
END 
insert into @Table values (@rule_txt) 
select stuff((SELECT ' '+isnull(replacement,charval) 
from @Table T left join masks M on M.mask=T.charval 
    for xml path('')),1,1,'') 
drop table rules 
drop table masks