J'ai besoin d'un moyen de comparer le contenu de deux colonnes varchar
, nommées fistname
et lastname
en conséquence, et si le contenu existe dans firstname
, puis supprimez-le de lastname
. Idéalement, je voudrais faire ceci sans requête de mise à jour, mais si c'est le seul moyen d'y parvenir, je peux suivre cette voie.
Voici des exemples DDL et 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
Ce qui donne l'ensemble de résultats de:
firstname lastname
------------- ----------
Bridget Jones Jones, III
Butch Jones
Key West West
Bob Marly Junior
Mon jeu de résultats souhaité est:
firstname lastname
------------- --------
Bridget Jones , III
Butch Jones
Key West
Bob Marly Junior
Je veux supprimer le texte (c'est-à-dire le contenu) de la colonne lastname
s'il existe dans la colonne firstname
.
Comment cela peut-il être fait via une instruction UDF ou case dans SQL Server 2008 R2?
J'ai d'abord utilisé une fonction de chaîne fractionnée que j'ai empruntée (encore) à cela réponse . Et j'ai ajouté une colonne ID (je suppose que votre table a un champ PK pour identifier chaque enregistrement.)
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
Maintenant, en utilisant un CROSS APPLY avec vos données:
SELECT * FROM MyTable t1 CROSS APPLY fnSplit(t1.FirstName, ' ') t2 WHERE CHARINDEX(t2.Data, t1.LastName) > 0; GO
Vous pouvez identifier les enregistrements où LastName
contient un mot de FirstName
:
Id | Prénom | Nom | Données -: | : --------- : --------- | : ---- 1 | Bridget Jones | Jones, III | Jones 3 | Key West | Ouest | Ouest
En utilisant les identifiants renvoyés par la requête précédente, vous pouvez mettre à jour votre table:
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 lignes affectées
Et voici le résultat final:
SELECT * FROM MyTable; GO
Id | Prénom | Nom -: | : ------------ | : ------- 1 | Bridget Jones | , III 2 | Butch | Jones 3 | Key West | 4 | Bob Marly | Junior
dbfiddle --- (ici