2015-11-17 2 views
1

Моя схема выглядит примерно так:Pivot Повторные поля в BigQuery

userid:string 
timestamp:integer 
params:nested/repeated field with 2 fields 
    - name:string (possible values: "a", "b","c") 
    - value:string 

Я хочу, чтобы мой запрос, чтобы вернуть следующее:

userid, timestamp, a, b, c 
123, 1447799796, foo, bar, xyz 
233, 1447799900, bob, xxx, yyy 
: 
: 

Что самый простой способ сделать это?

ответ

2

, когда возможные значения известны заранее, и есть не то, что многие из них писать вручную SQL - вы можете использовать ниже:

SELECT 
    userid, 
    ts, 
    MAX(IF(params.name = "a", params.value, NULL)) WITHIN RECORD a, 
    MAX(IF(params.name = "b", params.value, NULL)) WITHIN RECORD b, 
    MAX(IF(params.name = "c", params.value, NULL)) WITHIN RECORD c 
FROM yourTable 

Если возможно значения «неизвестны» заранее и/или динамические от запуска до запуска, вы можете использовать ниже вспомогательный SQL для генерации вышерасположенного типа SQL.

SELECT 'select userid, ts, ' + 
    GROUP_CONCAT_UNQUOTED(
     'max(if(params.name = "' + STRING(params.name) + '", params.value, null)) 
     WITHIN RECORD as [' + STRING(params.name) + ']' 
    ) 
    + ' from yourTable ' 
FROM (SELECT params.name FROM yourTable GROUP BY params.name) 
+0

Спасибо, Майк, как насчет стандартной версии SQLQuery? – Florent

+0

@FlorentCailly - Хороший вопрос! С ноября 2015 года многое изменилось. Стандартный SQL BigQuery настоятельно рекомендуется в наши дни! Я мигрировал сюда давно :) за исключением того, когда мне нужно использовать моментальные снимки (которые все еще доступны в Legacy SQL Only) –

+0

Спасибо, Майк, не могли бы вы опубликовать обновление о том, как это сделать, используя стандартный SQL? По какой-то причине, когда я использую вышеописанную методологию, а затем агрегирую, я не получаю правильный результат. Если я использую 'FIRST' вместо' MAX', я получаю результат гораздо ближе, но все же не правильный результат. Вот вопрос: – Florent

1

Что-то вдоль этих линий:

SELECT 
    userid, 
    timestamp, 
    FIRST(name == "a", value, NULL) WITHIN RECORD a, 
    FIRST(name == "b", value, NULL) WITHIN RECORD b, 
    FIRST(name == "c", value, NULL) WITHIN RECORD c, 
FROM t 
Смежные вопросы