web-dev-qa-db-ja.com

BigQueryで配列内の要素を見つける方法

配列に特定のキーと値のペアがある行を検索しようとしています。 BigQueryテーブルの行は次のようになります。

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

次のように暗黙のUNNESTまたはCROSS JOINを使用することを考えましたが、ネストを解除すると複数の異なる行が作成されるため、機能しませんでした。

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

このリンク は、legacy SQLではなく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

以下のダミーデータでテストできます

#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

少なくとも1つのペアが配列にある場合に出力IPが必要な場合-WHERE句で>= 2>=1に変更する必要があります

5

cookie配列に重複するペアがないことが保証されている場合、ミハイルのソリューションは優れています。ただし、重複がある可能性がある場合は、代替ソリューションを次に示します。

#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) )

結果のみ

ip
-----------
192.168.1.1
3