ここでは、データ内で見つけて置き換えるスペルミスの表を維持することをお勧めします。これは、静的参照テーブル(推奨)で行うことも、テーブルを追加できない場合は、プロシージャ内のテーブル変数で十分です。
この個々の単語のリストを使用すると、再帰的なcteを使用してデータをループし、各スペルを置き換えて最終結果を返すことができます。このアプローチでは、提案された他の回答のいくつかのように、個々の単語のリストを維持するだけで、文全体を維持する必要はありません。重複する行がある場合には、row_number
とcount
を同じ順序で保持できるように、一時表にデータを挿入する必要があります。あなたが本当にフォールスルースイッチケースを必要とするようにそれはいないようですが、あなたはテーブル構造(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;
:以下のクエリから
出力、あなたを助けることははるかに簡単です。 – Mureinik
2つの列を含む表がある場合、 'wrongvalue、rightvalue'は、この表を修正する表に結合し、データの* set *全体を更新する' UPDATE'文を作ることができます。私はケースステートメントがどこに通って来るかわからない。 –
クエリは本質的に動的です。したがって、条件に基づいて選択されるこのようなマスタテーブルにCASE文があります。 - '%gov%'のような場所の場合THEN REPLACE(場所、 'gov'、 'govt') 正しくない各エントリのWHEN句 これは最適な実装ではないので、回避策があれば幸いです – Abishek