Icy*_*rts 3 sql-server t-sql sql-server-2008-r2
我需要一种方法来比较两varchar列的内容,命名fistname和lastname相应,如果内容存在于 中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 语句完成此操作?
首先,我使用了从这个答案中(再次)借用的拆分字符串函数。我添加了一个 ID 列(我想你的表有一些 PK 字段来标识每条记录。)
Run Code Online (Sandbox Code Playgroud)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
现在,对您的数据使用 CROSS APPLY:
Run Code Online (Sandbox Code Playgroud)SELECT * FROM MyTable t1 CROSS APPLY fnSplit(t1.FirstName, ' ') t2 WHERE CHARINDEX(t2.Data, t1.LastName) > 0; GO
您可以识别LastName包含以下任何单词的记录FirstName:
身份证 | 名字 | 姓氏 | 数据 -: | :------------ | :--------- | :---- 1 | 布里奇特·琼斯 | 琼斯三世 | 琼斯 3 | 基韦斯特 | 西 | 西
使用从先前查询返回的 ID,您可以更新您的表:
Run Code Online (Sandbox Code Playgroud)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; GO2 行受影响
这是最终的结果:
Run Code Online (Sandbox Code Playgroud)SELECT * FROM MyTable; GO身份证 | 名字 | 姓 -: | :------------ | :------- 1 | 布里奇特·琼斯 | , 三 2 | 布奇| 琼斯 3 | 基韦斯特 | 4 | 鲍勃·马利 | 初级
dbfiddle在这里
| 归档时间: |
|
| 查看次数: |
25228 次 |
| 最近记录: |