it-swarm.com.de

Wie vergleiche ich Strings in zwei verschiedenen VARCHAR-Spalten?

Ich brauche eine Möglichkeit, den Inhalt von zwei varchar Spalten mit den Namen fistname und lastname entsprechend zu vergleichen, und wenn der Inhalt in firstname vorhanden ist, Entfernen Sie es dann aus lastname. Idealerweise möchte ich dies ohne eine Update-Abfrage tun, aber wenn dies der einzige Weg ist, dies zu erreichen, kann ich diesen Weg gehen.

Hier ist Beispiel DDL und 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

Welches ergibt die Ergebnismenge von:

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

Meine gewünschte Ergebnismenge ist:

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

Ich möchte das Text (dh den Inhalt) aus der Spalte lastname entfernen, wenn es in der Spalte firstname vorhanden ist.

Wie kann dies über eine UDF- oder case-Anweisung in SQL Server 2008 R2 erfolgen?

3
IcyPopTarts

Zuerst habe ich eine Split-String-Funktion verwendet, die ich (wieder) von dieser Antwort ausgeliehen habe. Und ich habe eine ID-Spalte hinzugefügt (ich nehme an, Ihre Tabelle enthält ein PK-Feld, um jeden Datensatz zu identifizieren.)

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

Verwenden Sie jetzt eine CROSS APPLY mit Ihren Daten:

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

Sie können die Datensätze identifizieren, in denen LastName ein beliebiges Wort von FirstName enthält:

 Id | Vorname | Nachname | Daten 
 -: | : --------- : --------- | : ---- 
 1 | Bridget Jones | Jones, III | Jones 
 3 | Key West | West | West 

Mit den IDs, die von der vorherigen Abfrage zurückgegeben wurden, können Sie Ihre Tabelle aktualisieren:

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 Zeilen betroffen 

Und das ist das Endergebnis:

SELECT * FROM MyTable;
GO
 Id | Vorname | Nachname 
 -: | : ------------ | : ------- 
 1 | Bridget Jones | , III 
 2 | Butch | Jones 
 3 | Key West | 
 4 | Bob Marly | Junior  

dbfiddle --- (hier

7
McNets