2016-10-18 2 views
0

Ich versuche, einige Daten Bereinigung in SQL durchzuführen. Ich habe einen Stammdatentabelle, die für jeden der falschen Einträge wie diesefall durch case-Anweisung SQL-Implementierung

CASE when location LIKE '%gov%' THEN REPLACE <gov with govt> 
    when location LIKE '%primery%' THEN REPLACE <primery with primary> 

Z. B eine CASE-Anweisung hat .: Ich brauche ‚gov primery skool‘ ‚Regierung der Grundschule‘ zu werden. Es gibt ungefähr 40 solcher Wörter, die mit den richtigen Einträgen aktualisiert werden müssen. Also würde es für jede Kombination dieser Wörter nicht skalieren.

Ich habe einige Nachforschungen angestellt und festgestellt, dass SQL keine fall-case-Anweisung erlaubt, die in diesem Szenario geholfen hätte. Irgendwelche Ideen, wie dies umgesetzt werden kann?

+0

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

+2

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. –

+0

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

Antwort

0

Sie benötigen Update-Anweisung mit CASE Klausel.

UPDATE YourTabel 
SET  YourField= CASE 
         WHEN YourField= 'gov primery skool' THEN 'Government primary school' 
         WHEN YourField= 'ABC' THEN 'XYZ' 
         ELSE YourField 
        END 
+0

das Feld könnte auch 'gov skool primery' sein. Für diese Einträge gibt es verschiedene Permutationen. Im Idealfall möchte ich nach einem Wort in dieser Zeichenfolge suchen und dann ersetzen. Im Wesentlichen nach gov suchen und durch govt ersetzen und dann nach "primery" suchen und dann ersetzen und so weiter in der gleichen Zeichenfolge. – Abishek

+0

Verwenden Sie in diesem Szenario Funktion ersetzen mit '%'. –

+0

Ich habe das versucht. Ich habe '% primery' benutzt. Das Problem ist, sobald SQL dies ersetzt, geht es nicht weiter, um die nächste Prüfung in dem Fall wie '% skool' zu überprüfen. – Abishek

0

Sie können OR Zustand bei Anweisung verwenden.

update TableName 
    set Field = case when fieldname='gov primery skool' or fieldname='gov skool primery' then 'Government primary school' 
    else fieldname end 
1

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;