Ich denke, die beste Wette, die Sie hier haben, ist eine Tabelle von Fehlbuchstabierungen zu erhalten, die Sie innerhalb Ihrer Daten suchen und ersetzen möchten. Dies kann entweder mit einer statischen Referenztabelle geschehen (empfohlen) oder wenn Sie keine Tabellen hinzufügen können, reicht eine Tabellenvariable innerhalb einer Prozedur aus.
Mit dieser Liste einzelner Wörter können Sie dann Ihre Daten mit einer rekursiven CTE durchlaufen, um jeden Rechtschreibfehler nacheinander zu ersetzen und das Endergebnis zurückzugeben. Bei diesem Ansatz müssen Sie nur die Liste der einzelnen Wörter und nicht die ganzen Sätze gemäß den anderen vorgeschlagenen Antworten pflegen. Sie müssen Ihre Daten in eine temporäre Tabelle einfügen, damit die Zeilen row_number
und count
in der gleichen Reihenfolge bleiben, falls Sie doppelte Zeilen haben.
Ausgabe von Abfrage unter:
TextValue | NewTextValue
----------------------+----------------------
gov primery skool | govt primary school
Not so incorect name | Not so incorrect name
-- Create data to use.
declare @Data table (TextValue nvarchar(50));
declare @Lookup table (IncorrectValue nvarchar(50),CorrectValue nvarchar(50));
insert into @Data values
('gov primery skool')
,('Not so incorect name');
insert into @Lookup values
('gov','govt')
,('primery','primary')
,('skool','school')
,('incorect','incorrect');
-- Actual query.
if object_id('tempdb..#DataRN') is not null
drop table #DataRN;
create table #DataRN (rn int
,cnt int
,cntrn int
,TextValue nvarchar(50)
,IncorrectValue nvarchar(50)
,CorrectValue nvarchar(50)
);
-- Create temp table that holds source data as well as some Row Numbers and Counts by TextValue to determine what order to retreive rows and to know which is the final row to pull out at the end.
insert into #DataRN
select row_number() over (order by d.TextValue, l.IncorrectValue, l.CorrectValue) as rn -- Provides order to select rows in cte below.
,row_number() over (partition by d.TextValue
order by d.TextValue, l.IncorrectValue, l.CorrectValue) as cntrn -- Provides ordering within each TextValue, to be compared with
,count(*) over (partition by d.TextValue) as cnt -- The total number of rows returned to complete all REPLACEs on the TextValue to find the last, and therefore complete, NewTextValue in cte.
,d.TextValue
,l.IncorrectValue
,l.CorrectValue
from @Data d
left join @Lookup l
on(d.TextValue like '%' + l.IncorrectValue + '%');
-- Recursive cte to apply each find and replace in order.
with cte as
(
select d.rn
,d.cnt
,d.cntrn
,d.TextValue
,cast(replace(d.TextValue,d.IncorrectValue,d.CorrectValue) as nvarchar(50)) as NewTextValue
from #DataRN d
where rn = 1
union all
select d.rn
,d.cnt
,d.cntrn
,d.TextValue
,cast(replace(case when d.TextValue = c.TextValue
then c.NewTextValue
else d.TextValue
end
,d.IncorrectValue
,d.CorrectValue
) as nvarchar(50)) as NewTextValue
from #DataRN d
inner join cte c
on(d.rn = c.rn+1)
)
select TextValue
,NewTextValue
from cte
where cnt = cntrn -- Where these two values are the same, we know that is the finished product.
order by 1;
if object_id('tempdb..#DataRN') is not null
drop table #DataRN;
Es scheint nicht, wie Sie wirklich eine fallthrough switch-case benötigen, aber wenn Sie die Tabellenstruktur (en) und einige Beispieldaten gemeinsam nutzen Es wäre viel einfacher, dir zu helfen. – Mureinik
Wenn Sie eine Tabelle haben, die zwei Spalten enthält - "falscherWert, rechterWert", dann sollten Sie in der Lage sein, eine 'UPDATE'-Anweisung zu erstellen, die diese Tabelle mit der zu korrigierenden verknüpft und den gesamten * Satz * von Daten aktualisiert. Ich habe keine Ahnung, wo Case Statements hinkommen oder gar durchkommen. –
Die Abfrage ist dynamisch in der Natur. So habe ich jetzt eine CASE-Anweisung in der Master-Tabelle wie folgt, die basierend auf einer Bedingung abgeholt wird - CASE WHEN Ort wie '% gov%' DANN ERSETZEN (Standort, 'gov', 'govt') Ich habe eine WHEN-Klausel für jeden der fehlerhaften Einträge Dies ist möglicherweise nicht die beste Implementierung, so dass jede Umgehungslösung würde geschätzt werden – Abishek