如何比较两个不同 VARCHAR 列中的字符串?

Icy*_*rts 3 sql-server t-sql sql-server-2008-r2

我需要一种方法来比较两varchar列的内容,命名fistnamelastname相应,如果内容存在于 中firstname,则将其从lastname. 理想情况下,我想在没有更新查询的情况下执行此操作,但如果这是实现它的唯一方法,那么我可以走那条路。

这是示例 DDL 和 DML:

Declare @BadData Table
(
    firstname varchar(500)
    ,lastname varchar(500)
)

Insert Into @BadData (firstname, lastname) Values
('Bridget Jones', 'Jones, III'), ('Butch', 'Jones'), ('Key West', 'West')
,('Bob Marly', 'Junior')

Select * From @BadData
Run Code Online (Sandbox Code Playgroud)

这给出了以下结果集:

firstname       lastname
-------------   ----------
Bridget Jones   Jones, III
Butch           Jones
Key West        West
Bob Marly       Junior
Run Code Online (Sandbox Code Playgroud)

我想要的结果集是:

firstname       lastname
-------------   --------
Bridget Jones   , III
Butch   Jones
Key West    
Bob Marly       Junior
Run Code Online (Sandbox Code Playgroud)

我想从列中删除文本(即内容),lastname如果它存在于firstname列中。

如何通过 SQL Server 2008 R2 中的 UDF 或 case 语句完成此操作?

McN*_*ets 7

首先,我使用了从这个答案中(再次)借用的拆分字符串函数。我添加了一个 ID 列(我想你的表有一些 PK 字段来标识每条记录。)

CREATE TABLE MyTable
(
    Id int IDENTITY,
    FirstName varchar(500),
    LastName varchar(500)
)

INSERT INTO MyTable (FirstName, LastName) 
VALUES ('Bridget Jones', 'Jones, III'), ('Butch', 'Jones'), ('Key West', 'West'),('Bob Marly', 'Junior');
GO
Run Code Online (Sandbox Code Playgroud)
CREATE FUNCTION dbo.fnSplit(@Input Varchar(1000), @Splitter VarChar(10)) 
RETURNS TABLE AS
RETURN
    SELECT Split.a.value('.', 'VARCHAR(1000)') AS Data 
    FROM (SELECT CAST ('<M>' + REPLACE(@Input, @Splitter, '</M><M>') + '</M>' AS XML) AS Data) AS A 
    CROSS APPLY Data.nodes ('/M') AS Split(a);
GO
Run Code Online (Sandbox Code Playgroud)

现在,对您的数据使用 CROSS APPLY:

    SELECT *
    FROM   MyTable t1 
    CROSS APPLY fnSplit(t1.FirstName, ' ') t2
    WHERE CHARINDEX(t2.Data, t1.LastName) > 0;
GO
Run Code Online (Sandbox Code Playgroud)

您可以识别LastName包含以下任何单词的记录FirstName

身份证 | 名字 | 姓氏 | 数据
-: | :------------ | :--------- | :----
 1 | 布里奇特·琼斯 | 琼斯三世 | 琼斯
 3 | 基韦斯特 | 西 | 西

使用从先前查询返回的 ID,您可以更新您的表:

WITH found AS
(
    SELECT Id, FirstName, LastName, Data
    FROM   MyTable t1 
    CROSS APPLY fnSplit(t1.FirstName, ' ') t2
    WHERE CHARINDEX(t2.Data, t1.LastName) > 0
)
UPDATE     T1
SET        T1.LastName = RTRIM(LTRIM(REPLACE(T1.LastName, Data, '')))
FROM       MyTable t1
INNER JOIN found t2
ON         t1.Id = t2.Id;
GO
Run Code Online (Sandbox Code Playgroud)
2 行受影响

这是最终的结果:

SELECT * FROM MyTable;
GO
Run Code Online (Sandbox Code Playgroud)
身份证 | 名字 | 姓
-: | :------------ | :-------
 1 | 布里奇特·琼斯 | , 三   
 2 | 布奇| 琼斯   
 3 | 基韦斯特 |         
 4 | 鲍勃·马利 | 初级  

dbfiddle在这里