web-dev-qa-db-ja.com

STRING_SPLITと複数文字のセパレーター

SQL Server 2016は STRING_SPLIT を導入しました。これは非常に高速で、2016年より前に開発された自家製の実装の優れた代替品です。

残念ながら、STRING_SPLITは1文字のセパレータのみをサポートしているため、常に十分であるとは限りません。セパレータで複数の文字を使用できる優れた実装を知っている人はいますか?

8
Petter Brodin

まあ、いつでもREPLACEを使用して、引数に渡す前に1文字の区切り文字を追加できます。実際のデータに表示される可能性が低い/不可能である文字を選択するだけです。この例では、元のデータが区切り文字として3つのパイプを使用しているとします。代わりにランダムにUnicode文字を選択しました。

DECLARE 
  @olddelim nvarchar(32) = N'|||', 
  @newdelim nchar(1)     = NCHAR(9999); -- pencil (✏)

DECLARE @x nvarchar(max) = N'foo|||bar|||blat|||splunge';

SELECT * FROM STRING_SPLIT(REPLACE(@x, @olddelim, @newdelim), @newdelim);

私はこれについてここでより詳細にブログに書いた:


コメントへの対処:

悪い解決策。元の文字列が 'abc || pqr ||| rst || 123'(動的で何でも含むことができる)の場合はどうなりますか?必要なo/pは 'abc || pqr'および 'rst || 123'ですが、ソリューションでは 'abc' 'pqr' 'rst' '123'が得られます

さて、あなたの入力を取り、私のソリューションが間違った出力を取得するかどうか見てみましょう。

DECLARE 
  @olddelim nvarchar(32) = N'|||', 
  @newdelim nchar(1)     = NCHAR(9999); -- pencil (✏)

DECLARE @x nvarchar(max) = N'abc||pqr|||rst||123';

SELECT * FROM STRING_SPLIT(REPLACE(@x, @olddelim, @newdelim), @newdelim);

結果は次のとおりです。

abc||pqr
rst||123

そして、あなたが仮定しなければならないものではありません(しかしテストしていません):

abc
pqr
rst
123

データがテーブル内にある場合は、ビューを作成して、その式をすべてのクエリに含める必要がないようにすることができます。


データに鉛筆()が含まれている可能性があり、 1,111,998の使用可能なUnicode文字 データセットに含まれないため、STRING_SPLIT()はスキップする必要があります。これは、単一文字の区切り文字( separator Is a single character expression )。

代替案はここ 数十回前 に回答されており、STRING_SPLIT()が存在する前に何度も回答されました。これらの方法は引き続き機能します。

私は多くの代替案を検討し、このシリーズのSTRING_SPLIT()で制限についても説明します(T-SQLでメソッドを使用せずにこれを行わないことを検討する理由についても説明します)。

19
Aaron Bertrand