この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
将来的なデータ分析に備えウェブブラウザからPOSTされたデータをそのままファイルやレコードに登録しているケースでは、分析対象のデータのカラムにカンマ区切りデータがそのまま格納されていることがあります。このままではデータ分析用途のデータとして不向きなので、複数レコードに分解する必要があります。 Amazon Athenaでは、split関数と「CROSS JOIN UNNEST」構文を利用して簡単に複数レコードに分解することができます。
サンプルTSVファイル
ファイルはタブ区切りで、3つ目のフィールドがカンマ区切りのフィールドです。今回は6種類のレコードを用意しました。1〜3は正常なカンマ区切りデータです。これだけでは面白くないので、4〜6はあえて異常なカンマ区切りデータを用意しました。
1 ok1 1
2 ok2 2,3
3 ok3 4,5,6
4 ng1 7,
5 ng2 ,8
6 ng3 ,9,
テーブル定義
CREATE EXTERNAL TABLE IF NOT EXISTS comma_data (
id int,
name string,
categories string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '\t',
'field.delim' = '\t'
)LOCATION 's3://<bucketname>/comma_data/';
SELECTの例
categoriesカラムを参照するとカンマ区切り文字がそのまま表示されます。
SELECT id, name, categories
FROM comma_data t1;
split関数と「CROSS JOIN UNNEST」構文を利用して、categoriesカラムのデータをカンマ「,」区切りして、categoryカラムの複数レコードとして分割します。
SELECT id, name, category
FROM comma_data t1
CROSS JOIN UNNEST(
split(t1.categories, ',')
) AS t (category)
;
カンマ区切り文字が複数レコードに分解されました。カンマのみの場合は値がないカラムとして出力されています。
値がないカラムのレコードを取り除くには、「category IS NOT NULL」ではなく、「category <> ''」と指定します。categoryはNULLではないようです。
SELECT id, name, category
FROM comma_data t1
CROSS JOIN UNNEST(
split(t1.categories, ',')
) AS t (category)
WHERE category <> ''
;
最後に
正常なカラムデータではない場合でもエラーにならずレコードとして分解されることが確認できました。データ分析の要件に合わせ必要に応じて、不要なレコードを除去する条件を指定することができるので、簡易なETLにも活用できそうです。