2016-10-18 6 views
0

SQLでいくつかのデータクレンジングを実行しようとしています。私はこのfall caseステートメントSQLインプリメンテーション

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

のような間違ったエントリー例えば:私は「政府小学校」になるために 'primery SKOOLをGOVのニーズごとに、CASE文を持っているマスタデータテーブルを持っています。正しいエントリで更新する必要があるこのような単語は約40件あります。だから、これらの言葉のあらゆる組み合わせについてそれを行うことは、拡大しないでしょう。

私はいくつかの調査を行いましたが、SQLではこのシナリオで役立つはずの転倒事例が許可されていないことが判明しました。これをどのように実装できるかについてのアイデアはありますか?

+0

:以下のクエリから

出力、あなたを助けることははるかに簡単です。 – Mureinik

+2

2つの列を含む表がある場合、 'wrongvalue、rightvalue'は、この表を修正する表に結合し、データの* set *全体を更新する' UPDATE'文を作ることができます。私はケースステートメントがどこに通って来るかわからない。 –

+0

クエリは本質的に動的です。したがって、条件に基づいて選択されるこのようなマスタテーブルにCASE文があります。 - '%gov%'のような場所の場合THEN REPLACE(場所、 'gov'、 'govt') 正しくない各エントリのWHEN句 これは最適な実装ではないので、回避策があれば幸いです – Abishek

答えて

0

ケースとの更新文が必要です。

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

フィールドは 'gov skool primery'でもかまいません。これらのエントリにはさまざまな順列があります。理想的には、その文字列内の単語をチェックして置き換えたいと思います。基本的にgovを探し、govtで置き換えてから、同じ文字列で "primery"を探して置き換えてください。 – Abishek

+0

このシナリオでは、Replace関数を '%'で置き換えます。 –

+0

私はそれを試みました。私は '%primery'を使用しました。問題は、SQLがこれを置き換えると、 '%skool'のような場合に次のチェックをチェックしないようになります。 – Abishek

0

あなたはcase文でOR条件を使用することができます。

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

ここでは、データ内で見つけて置き換えるスペルミスの表を維持することをお勧めします。これは、静的参照テーブル(推奨)で行うことも、テーブルを追加できない場合は、プロシージャ内のテーブル変数で十分です。

この個々の単語のリストを使用すると、再帰的なcteを使用してデータをループし、各スペルを置き換えて最終結果を返すことができます。このアプローチでは、提案された他の回答のいくつかのように、個々の単語のリストを維持するだけで、文全体を維持する必要はありません。重複する行がある場合には、row_numbercountを同じ順序で保持できるように、一時表にデータを挿入する必要があります。あなたが本当にフォールスルースイッチケースを必要とするようにそれはいないようですが、あなたはテーブル構造(S)といくつかのサンプルデータを共有している場合

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; 
関連する問題