2017-12-05 8 views
2

残念ながらBQで再整形するのはRほど簡単ではなく、このプロジェクトのデータをエクスポートできません。大きなクエリ(標準SQL)でワイドからロングまでの変形

ここで入力

date country A    B   C  D 
20170928 CH 3000.3  121  13  3200 
20170929 CH 2800.31  137  23  1614.31 

の予想される出力

date country Metric Value 
20170928 CH A  3000.3 
20170928 CH B  121  
20170928 CH C  13  
20170928 CH D  3200 
20170929 CH A  2800.31 
20170929 CH B  137  
20170929 CH C  23  
20170929 CH D  1614.31 

はまた私のテーブルには、より多くの列と行を持っている(私は、マニュアルの多くが必要となります)と仮定されて

答えて

1

以下はBigQuery Standard SQLを対象としており、繰り返しの選択は必要ありません。列の数によって異なります。それはあなたが持っている限り多くのを選んで、メトリクスにそれらを変換し、あなたが/テスト

#standardSQL 
WITH `project.dataset.yourtable` AS (
    SELECT '20170928' DATE, 'CH' country, 3000.3 A, 121 B, 13 C, 3200 D UNION ALL 
    SELECT '20170929', 'CH', 2800.31, 137, 23, 1614.31 
) 
SELECT DATE, country, 
    metric, SAFE_CAST(value AS FLOAT64) value 
FROM (
    SELECT DATE, country, 
    REGEXP_REPLACE(SPLIT(pair, ':')[OFFSET(0)], r'^"|"$', '') metric, 
    REGEXP_REPLACE(SPLIT(pair, ':')[OFFSET(1)], r'^"|"$', '') value 
    FROM `project.dataset.yourtable` t, 
    UNNEST(SPLIT(REGEXP_REPLACE(to_json_string(t), r'{|}', ''))) pair 
) 
WHERE NOT LOWER(metric) IN ('date', 'country') 

結果が期待されているとして、あなたの質問のように、ダミーデータを使用して、上記で遊ぶことができます

#standardSQL 
SELECT DATE, country, 
    metric, SAFE_CAST(value AS FLOAT64) value 
FROM (
    SELECT DATE, country, 
    REGEXP_REPLACE(SPLIT(pair, ':')[OFFSET(0)], r'^"|"$', '') metric, 
    REGEXP_REPLACE(SPLIT(pair, ':')[OFFSET(1)], r'^"|"$', '') value 
    FROM `project.dataset.yourtable` t, 
    UNNEST(SPLIT(REGEXP_REPLACE(to_json_string(t), r'{|}', ''))) pair 
) 
WHERE NOT LOWER(metric) IN ('date', 'country') 

値になる

DATE  country metric value  
20170928 CH  A  3000.3 
20170928 CH  B  121.0  
20170928 CH  C  13.0  
20170928 CH  D  3200.0 
20170929 CH  A  2800.31 
20170929 CH  B  137.0  
20170929 CH  C  23.0  
20170929 CH  D  1614.31 
1

あなたが必要UNION bigqueryでコンマを使用して表します。

SELECT date, country, Metric, Value 
FROM (
    SELECT date, country, 'A' as Metric, A as Value FROM your_table 
), (
    SELECT date, country, 'B' as Metric, B as Value FROM your_table 
), (
    SELECT date, country, 'C' as Metric, C as Value FROM your_table 
) , (
    SELECT date, country, 'D' as Metric, D as Value FROM your_table 
) 
+0

これはうまくいきますが、標準SQLの場合は、実際には '' 'UNION ALL'''を使用する必要があります。 ありがとう! – AlienDeg

+0

@AlienDeg 'date'がユニークであれば(これは私が信じる)、' UNION'と 'UNION ALL'の間に違いはありません。あなたは歓迎です:) –

+0

私が意味するのは、UNIONは標準SQLで昏睡状態を使用して指定されていないということです。 – AlienDeg

関連する問題