2017-10-19 11 views
0

J'ai une table imbriquée que je ne peux pas accéder à tous les champs d'utilisation de google bigquery standard.Impossible de désimporter certains champs en utilisant google bigquery (standard)

Par exemple, cette requête échoue

SELECT * 
FROM 
    (
    SELECT 
      rev_info.user.id as player_id, 
      rev_info.purchase.total.currency as currency, 
      rev_info.purchase.total.amount as REV 
      ,rev_info.purchase.virtual_items.items.sku  as sku 
    FROM `gcs.rev` 
    ) 
WHERE currency = 'USD' 

avec l'erreur

"Error: Cannot access field sku on a value with type ARRAY> at [9:59]"

cependant

SELECT * 
FROM 
    (
    SELECT 
      rev_info.user.id as player_id, 
      rev_info.purchase.total.currency as currency, 
      rev_info.purchase.total.amount as REV 
      --,rev_info.purchase.virtual_items.items.sku as sku 
    FROM `gcs.rev` 
    ) 
WHERE currency = 'USD' 

Cette requête est très bien.

Notez également que

SELECT 
     rev_info.purchase.virtual_items.items.sku  as sku 
FROM `gcs.rev` 

échoue avec la même erreur que ci-dessus.

+0

ce que vous entendez par « pas t o ne pas nicher ... "? tu n'as même pas essayé! au moins, c'est comme cela que cela ressemble à partir des questions dans votre question! –

+0

Bonjour et bienvenue sur Stackoverflow! Si les réponses que vous avez reçues vous ont aidé de quelque façon que ce soit ou résolu votre problème, envisagez d'accepter et de voter, car c'est important dans ce forum: https://stackoverflow.com/help/someone-answers –

Répondre

1

Expansion sur la réponse Elliott - Je pense ici que vous devez d'abord UNNEST, mais alors vous avez probablement besoin de regrouper vos arrière sku « s. sinon vous obtiendrez toute sortie redondante (aplatie)

Je me sens ci-dessous est ce que vous pourriez avoir besoin - il est pour BigQuery standard SQL

#standardSQL 
SELECT 
    player_id, 
    currency, 
    REV, 
    STRING_AGG(sku) SKUs 
FROM (
    SELECT 
    rev_info.user.id AS player_id, 
    rev_info.purchase.total.currency AS currency, 
    rev_info.purchase.total.amount AS REV, 
    item.sku AS sku 
    FROM `gcs.rev` t, 
    UNNEST(t.rev_info.purchase.virtual_items.items) item 
) 
WHERE currency = 'USD' 
GROUP BY 1, 2, 3 

Ainsi, tous sku sera présenté comme une liste donnée player_id, ainsi que le montant et la devise

Ajouté, selon un commentaire/suggestion de Elliott

#standardSQL 
SELECT 
    rev_info.user.id AS player_id, 
    rev_info.purchase.total.currency AS currency, 
    rev_info.purchase.total.amount AS REV, 
    (SELECT STRING_AGG(item.sku) 
    FROM UNNEST(t.rev_info.purchase.virtual_items.items) item 
) AS SKUs 
FROM `gcs.rev` t, 
WHERE currency = 'USD' 
+0

Ou peut-être 'ARRAY (SELECT sku FROM UNNEST (t.rev_info.purchase.virtual_items.items))' AS sku pour éviter l'agrégation (vous pouvez utiliser 'STRING_AGG' en alternative). –

+0

Totalement d'accord. Si c'était mon code - j'utiliserais probablement quelque chose comme '(SELECT STRING_AGG (item.sku) FROM UNNEST (...) article) AS SKUs sans' GROUP BY' et sans 'SELECT *', etc. J'ai appris ici que chaque jour pendant les deux dernières années, OP essayait de "simplifier"/obscurcir son code dans de nombreux cas en laissant dehors "petit" de ses éléments potentiels mais vraiment importants qui importent, mais habituellement ils ne pas transformer/changer la structure de la requête. SO dans ce cas - 'SELECT *' semblait un peu suspect pour moi alors j'ai essayé de ne pas changer la requête interne –

1

Si votre objectif est d'obtenir une ligne pour chaque élément de tableau items, vous pouvez utiliser l'opérateur de virgule (join) entre la table et rev_info.purchase.virtual_items.items. Par exemple,

SELECT * 
FROM (
    SELECT 
    rev_info.user.id as player_id, 
    rev_info.purchase.total.currency as currency, 
    rev_info.purchase.total.amount as REV, 
    item.sku as sku 
    FROM `gcs.rev` t, 
    t.rev_info.purchase.virtual_items.items item 
) 
WHERE currency = 'USD' 
+0

Merci, ça marche! Cependant, je suis confus quant à savoir pourquoi il est nécessaire pour SKU et non rev ou monnaie. En particulier, je ne comprends pas pourquoi l'aplatissement automatique de cette norme ne semble pas le faire directement. – user2998362

+0

C'est uniquement nécessaire pour 'sku' car le champ le contenant (' items') est un tableau. Pour les autres chemins de champ tels que 'currency' et' amount', il n'y a pas de tableau le long du chemin. Lors de l'utilisation de SQL standard, il n'y a pas d '"aplatissement automatique"; vous devez exprimer vos intentions explicitement (comme avec l'opérateur de virgule dans ce cas). –