2016-10-18 4 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> 

같은 잘못된 항목 각각에 대해 CASE 문 예컨대이있는 마스터 데이터 테이블이 : 내가 필요로하는 '정부 초등학교'가 될 'primery skool를 GOV'. 올바른 항목으로 업데이트해야하는 약 40 개의 단어가 있습니다. 그래서이 단어들의 각각의 모든 조합에 대해 그것을하는 것은 확장되지 않을 것입니다.

나는 약간의 조사를했는데 SQL은이 시나리오에서 도움이되었을 경우를 대비 한 추론을 허용하지 않는다는 것을 알아 냈습니다. 이것이 어떻게 구현 될 수 있는지에 대한 아이디어가 있습니까?

+0

그것은 당신이 정말 위해 fallthrough 스위치의 경우 필요한 것처럼 보이지만,하지 않습니다 당신은 테이블 구조 (들) 및 일부 샘플 데이터를 공유하는 경우 , 당신을 도우는 것이 훨씬 쉬울 것입니다. – Mureinik

+2

두 개의 컬럼을 포함하는 테이블을 가지고 있다면 - 'wrongvalue, rightvalue' 그러면이 테이블을 수정할 테이블에 조인하고 데이터의 전체 * 세트 *를 업데이트하는 UPDATE 문을 만들어야합니다. 사례 진술이나 추락이 어디로 들어 왔는지 전혀 모르겠습니다. –

+0

쿼리는 사실상 동적입니다. 그래서 내가 조건을 기반으로 집어 오는이 같은 마스터 테이블에있는 CASE 문을 가지고 - '% gov %'와 같은 위치 때 그때 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

이 시나리오에서는 '%'로 바꾸기 기능을 사용하십시오. –

+0

나는 그것을 시도했다. 나는 '% primery'를 사용했다. 이 문제는 SQL을 대체하면 '% skool'같은 경우에 다음 검사를 확인하지 않습니다. – Abishek

0

당신은 case 문에 또는 조건을 사용할 수 있습니다.

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을 동일한 순서로 유지할 수 있도록 임시 테이블에 데이터를 삽입해야합니다. 아래 쿼리

출력 :

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;