web-dev-qa-db-ja.com

2つの異なるVARCHAR列の文字列を比較する方法は?

varcharおよびfistnameという名前の2つの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

次の結果セットが得られます。

firstname       lastname
-------------   ----------
Bridget Jones   Jones, III
Butch           Jones
Key West        West
Bob Marly       Junior

私の望ましい結果セットは:

firstname       lastname
-------------   --------
Bridget Jones   , III
Butch   Jones
Key West    
Bob Marly       Junior

lastname列に存在する場合、firstname列からtext(つまり、コンテンツ)を削除します。

これは、SQL Server 2008 R2でUDFまたはcaseステートメントを使用してどのように実行できますか?

3
IcyPopTarts

最初に、これから(再度)借りた分割文字列関数を使用しました answer 。そして、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
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を使用します。

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

LastNameFirstNameの単語が含まれているレコードを特定できます。

 Id | FirstName |姓|データ
-:| :--------- :--------- | :---- 
 1 |ブリジット・ジョーンズ|ジョーンズ、III |ジョーンズ
 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
 2行が影響を受けました

そしてこれが最終結果です:

SELECT * FROM MyTable;
GO
 Id | FirstName | LastName 
-:| :------------ | :------- 
 1 |ブリジット・ジョーンズ| 、III 
 2 |ブッチ|ジョーンズ
 3 |キーウェスト| 
 4 |ボブ・マーリー|ジュニア

dbfiddle ---(ここ

7
McNets