2017-03-16 105 views
0

我试图解决的问题是使用REPLACE函数来查看槽的值列表并进行所有各种替换,但挑战在于这在不同的桌子上。基本上,我正在寻找比做25-100个REPLACE函数更聪明的方法。SQL使用REPLACE函数搜索表变量并更新字段

这里是问题的简化版本: 变量表保存字符/字符串列表(随机长度和混合字符)我想稍后找到并替换。

DECLARE @ReplaceList TABLE (String VARCHAR(100)) 
INSERT INTO @ReplaceList (String) 
VALUES ('AAA1 - '), ('AAB1 - '), ('A3 !'), ('BC4 - ') 

String 
AAA1 - 
AAB1 - 
A3 ! 
BC4 - 

然后,我有一个表(职位)超过千行与需要所有这些替换/删除描述。所需

Title 
AAA1 - Job 1 
AAA1 - Job 2 
A3 ! Job 4 
BC4 - Job 5 

最终的结果是:

Title 
Job 1 
Job 2 
Job 4 
Job 5 

粗糙的想法我曾经为SQL代码脱节将类似于

SELECT REPLACE(Jobs.Title,@ReplaceList.String,'') 
FROM Jobs 

我知道这个代码是没有在附近什么实际上它可能会工作,因为它可能需要一个子查询或其他东西,但我认为它表达了使用来自变量表的数据作为在不同表的每个字段中要替换的主列表的想法。

+0

也许交叉应用将有助于... –

+0

你想删除'Job'左边的字符串? ...你正在使用哪个数据库? – scaisEdge

+0

我删除了冲突的DBMS标签。请为您实际使用的DBMS添加一个。 –

回答

0

我没有看到一个联接与更换工作相结合。您需要为每个字符串应用REPLACE函数一次 - 也就是行 - 进行搜索和替换,每次后续检查都需要输入前一个结果。所以,迭代是必需的。

下面将做到这一点。我构建了搜索表以允许完整的字符串替换 - 只需将“ReplaceWith”设置为空字符串即可将文本填充为空。 (请注意,当您用其他本身需要替换的文本替换文本时,将搜索订单字符串)

这对于大数据集不会太好,因为您需要经过目标每个搜索字符串一次,并且您将更新每个遍中的每一行。

SET NOCOUNT on 


-- Set up table of strings to search through 
DECLARE @Jobs TABLE 
(Title varchar(100) not null) 

INSERT @Jobs values 
    ('AAA1 - Job 1, box ') 
,('AAA1 - Job 2, fox ') 
,('A3 ! Job 4 ') 
,('BC4 - Job 5') 
,('The quick red fox') 

SELECT * 
from @Jobs 


-- Set up table of search-and-replace strings 
DECLARE @ReplaceList TABLE 
(
    LookFor  varchar(100) not null 
    ,ReplaceWith varchar(100) not null 
    ,ReplaceOrder int   not null PRIMARY KEY 
) 

INSERT @ReplaceList values 
    ('AAA1 - ', 'AA1 - ', 1) 
,('AAB1 - ', 'AB1 - ', 2) 
,('A3 !', 'A3 - ', 3) 
,('BC4 - ', 'XXX - ', 4) 
,('fox', 'lox', 5) 
,(' ', ' ', 6) 

SELECT * 
from @ReplaceList 



DECLARE 
    @LoopCheck int 
,@NextToDo  int 
,@ReplaceThis varchar(100) 
,@ReplaceWith varchar(100) 


SET @LoopCheck = 0 


WHILE @LoopCheck is not null 
BEGIN 
    -- Loop is processed once for every row in @ReplaceList 

    SET @NextToDo = null 

    -- Get the next replace string to check 
    SELECT 
     @NextToDo = min(ReplaceOrder) 
    from @ReplaceList 
    where ReplaceOrder > @LoopCheck 


    IF @NextToDo is null 
     -- No more to do, exit out 
     BREAK 


    -- Get the replacement strings 
    SELECT 
     @ReplaceThis = LookFor 
     ,@ReplaceWith = ReplaceWith 
    from @ReplaceList 
    where ReplaceOrder = @NextToDo 


    -- Update all target strings as necessary 
    UPDATE @Jobs 
    set Title = replace(Title, @ReplaceThis, @ReplaceWith) 


    -- On to the next one 
    SET @LoopCheck = @NextToDo 
END 


-- Waddawe got? 
SELECT * 
from @Jobs 
+0

这正是我所期待的,它涵盖了我的大型实际数据库中出现的所有其他情况。谢谢你的帮助! – Cory

+0

我对此有一个跟进问题,如果我想让这个行为更像是一个被选中的字段的函数,那么代码如何改变。例如,而不是创建一个我加入的全新变量表。我希望我把它作为一个函数(我们称之为CustomReplace),可以在select语句中使用它。从@Jobs中选择CustomeReplace(标题)。这样,它会查看一个值并遍历'at'Replace列表表格,而不会创建需要重新加入的整个单独表格。 – Cory

+0

我会将上面的代码修改为适合多语句函数调用(检出'CREATE FUNCTION'),唯一的参数是要修改的值。但请注意,如果嵌套在较大的查询中,则此类函数会严重降低性能。 –

0

在mysql中,这将帮助你。

select replace(j.Title,rl.string, '') from ReplaceList rl , job j where j.Title like concat('%',rl.string_,'%'); 
+0

这非常有帮助,但我意识到,当我简化示例时,有一段小小的过度视线。列表中可能需要有多个事物需要用单个字符串替换。例如,一个值可以是'AAAA - 作业1 A3! - ',所以有两个替换需要在同一个字符串中发生。如何从@ReplaceList中替换所有的项目,而不是在第一个项目之后停止? – Cory

0

假设你的标题表可以与一些一致性进行格式化:

Create table #ReplaceList (String VARCHAR(100)) 
INSERT INTO #ReplaceList (String) 
VALUES ('AAA1 - '), ('AAB1 - '), ('A3 ! - '), ('BC4 - ') 

Select * from #ReplaceList; 

Create table #Title (mytitle varchar(50)) 
INSERT INTO #Title values ('AAA1 - Job 1'), ('AAA1 - Job 2'), ('A3 ! - Job 4'), ('BC4 - Job 5') 

Select * from #Title 

create table #string_job (string varchar(100), job varchar(50)) 
insert into #string_job 
select left(mytitle, 7) as string, 
     right(mytitle, 5) as job 
from #title 

select string, job from #string_job 

select J.job as 'Title' 
from #string_job J 
right join #ReplaceList R 
on R.string = J.string 
+0

问题在于标题格式不一致。我基本上只需要一个字符串列表,无论它们出现在标题字符串中的什么地方,都可以将其拉出。所以左()和右()不适用于我的实际情况。 – Cory