web-dev-qa-db-fra.com

Comment trouver des éléments dans un tableau dans BigQuery

J'essaie de rechercher une ligne qui a certaines paires de valeurs clés dans un tableau. Une ligne dans ma table BigQuery ressemblerait à quelque chose comme ça.

{
  "ip": "192.168.1.1",
  "cookie" [
    {
      "key": "Apple",
      "value: "red"
    },
    {
      "key": "orange",
      "value: "orange"
    },
    {
      "key": "grape",
      "value: "purple"
    }
  ]
}

J'ai pensé à utiliser UNNEST ou CROSS JOIN implicite comme ci-dessous, mais cela n'a pas fonctionné car le démanteler créerait simplement plusieurs lignes différentes.

SELECT ip
FROM table t, t.cookie c
WHERE (c.key = "grape" AND c.value ="purple") AND (c.key = "orange" AND c.value ="orange")

Ce lien est vraiment proche de ce que je veux faire, sauf qu'ils utilisent legacy SQL et non standardSQL

9
dorachan2010
#standardSQL
SELECT ip
FROM yourTable 
WHERE (
  SELECT COUNT(1) 
  FROM UNNEST(cookie) AS pair 
  WHERE pair IN (('grape', 'purple'),  ('orange', 'orange'))
) >= 2

vous pouvez le tester avec des données factices ci-dessous

#standardSQL
WITH yourTable AS (
  SELECT '192.168.1.1' AS ip, [('Apple', 'red'), ('orange', 'orange'), ('grape', 'purple')] AS cookie UNION ALL
  SELECT '192.168.1.2', [('abc', 'xyz')]
)
SELECT ip
FROM yourTable 
WHERE (
  SELECT COUNT(1) 
  FROM UNNEST(cookie) AS pair 
  WHERE pair IN (('grape', 'purple'),  ('orange', 'orange'))
) >= 2

Si vous avez besoin d'une sortie ip si au moins une paire est dans le tableau - vous devez changer >= 2 à >=1 dans WHERE clause

5
Mikhail Berlyant

La solution de Mikhail est bonne s'il est garanti qu'il n'y a pas de paires en double dans le tableau cookie. Mais s'il peut y avoir des doublons, voici la solution alternative:

#standardSQL
WITH yourTable AS (
  SELECT 
    '192.168.1.1' AS ip,
    [('Apple', 'red'), ('orange', 'orange'), ('grape', 'purple')] AS cookie UNION ALL
  SELECT
    '192.168.1.2',
    [('abc', 'xyz'), ('orange', 'orange'), ('orange', 'orange')]
)
SELECT ip
FROM yourTable t
WHERE (
  ('grape', 'purple')  IN UNNEST(t.cookie) AND
  ('orange', 'orange') IN UNNEST(t.cookie) )

Résultats en seulement

ip
-----------
192.168.1.1
3
Mosha Pasumansky