[Redshift] CHAR型のパターンマッチング

2016.10.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Redshift では LIKE 以外にも正規表現を用いたパターンマッチング条件を利用することができます。

下記のようなテーブルから、「数字だけで構成されるレコードのみ抽出」したい場合は

value [VARCHAR]
1234567890
2345678901
ABCDEFGHIJ
KLMNOPQRST
NULL

条件式を

value ~ '^[[:digit:]]+$'

などとします。

SELECT * FROM (
  SELECT '1234567890'::varchar AS value UNION
  SELECT '2345678901'::varchar AS value UNION
  SELECT 'ABCDEFGHIJ'::varchar AS value UNION
  SELECT 'KLMNOPQRST'::varchar AS value UNION
  SELECT NULL::varchar AS value
) WHERE value ~ '^[[:digit:]]+$';
value     
----------
1234567890
2345678901

しかし、データ型が CHAR 型の場合には注意が必要です。

value [CHAR(20)]
1234567890
2345678901
ABCDEFGHIJ
KLMNOPQRST
NULL

等価条件(=)の場合、以下のようなクエリでレコードが取得できるため

SELECT * FROM (
  SELECT '1234567890'::varchar AS value UNION
  SELECT '2345678901'::varchar AS value UNION
  SELECT 'ABCDEFGHIJ'::varchar AS value UNION
  SELECT 'KLMNOPQRST'::varchar AS value UNION
  SELECT NULL::varchar AS value
) WHERE value = '1234567890';
value     
----------
1234567890

ついつい先程と同様に「'^[[:digit:]]+$'」でマッチングできそうに思ってしまいますが

SELECT * FROM (
  SELECT '1234567890'::char(20) AS value UNION
  SELECT '2345678901'::char(20) AS value UNION
  SELECT 'ABCDEFGHIJ'::char(20) AS value UNION
  SELECT 'KLMNOPQRST'::char(20) AS value UNION
  SELECT NULL::char(20) AS value
) WHERE value ~ '^[[:digit:]]+$';
value     
----------

マッチングしません。

文字型 - Amazon Redshift」を参照すると以下のようにあります。

固定長の文字列を格納するには、CHAR または CHARACTER を使用します。これらの文字列は空白で埋められるので、CHAR(10) 列は常に 10 バイトのストレージを占有します。

CHAR 型データをパターンマッチングする場合はこの「空白で埋められる」を考慮する必要があります。

SELECT * FROM (
  SELECT '1234567890'::char(20) AS value UNION
  SELECT '2345678901'::char(20) AS value UNION
  SELECT 'ABCDEFGHIJ'::char(20) AS value UNION
  SELECT 'KLMNOPQRST'::char(20) AS value UNION
  SELECT NULL::char(20) AS value
) WHERE value ~ '^[[:digit:]]+[[:space:]]*$';
value               
--------------------
1234567890          
2345678901

マッチングさせることができました。

まとめ

値としては同じなのですが、データ型によって正規表現のパターンが異なることに注意が必要です。 また、ドキュメントに「“SIMILAR TO または POSIX の演算子を使用する正規表現マッチングは、計算コストが高くなります。”」とあるように、多くの行を処理する場合のパターンマッチングなどにも注意が必要です。