여기에있는 최선의 방법은 데이터 내에서 찾고 철자가 틀린 표를 유지하는 것입니다. 이는 정적 참조 테이블 (권장)을 사용하여 수행 할 수도 있고 테이블을 추가 할 수없는 경우 프로 시저 내의 테이블 변수로 충분할 수 있습니다.
이 개별 단어 목록을 사용하면 재귀 cte를 사용하여 데이터를 반복하여 각 맞춤법을 바꿔 최종 결과를 반환 할 수 있습니다. 이 접근 방식을 사용하면 제안 된 다른 답변에 따라 전체 단어가 아닌 개별 단어의 목록 만 유지하면됩니다. 중복 행이있는 경우에 대비하여 row_number
및 count
을 동일한 순서로 유지할 수 있도록 임시 테이블에 데이터를 삽입해야합니다. 아래 쿼리
이
출력 :
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;
그것은 당신이 정말 위해 fallthrough 스위치의 경우 필요한 것처럼 보이지만,하지 않습니다 당신은 테이블 구조 (들) 및 일부 샘플 데이터를 공유하는 경우 , 당신을 도우는 것이 훨씬 쉬울 것입니다. – Mureinik
두 개의 컬럼을 포함하는 테이블을 가지고 있다면 - 'wrongvalue, rightvalue' 그러면이 테이블을 수정할 테이블에 조인하고 데이터의 전체 * 세트 *를 업데이트하는 UPDATE 문을 만들어야합니다. 사례 진술이나 추락이 어디로 들어 왔는지 전혀 모르겠습니다. –
쿼리는 사실상 동적입니다. 그래서 내가 조건을 기반으로 집어 오는이 같은 마스터 테이블에있는 CASE 문을 가지고 - '% gov %'와 같은 위치 때 그때 REPLACE (위치, 'gov', 'govt') 내가 가지고있다 각각의 잘못된 항목에 대한 WHEN 절 이것은 최상의 해결책이 아니므로 모든 해결 방법을 이해할 수 있습니다. – Abishek