标准 SQL 中的 BigQuery 连接数组

pot*_*ion 6 sql google-bigquery

我正在使用标准 SQL 并且我有表Order

“订单”表

我正在尝试将其与表连接起来MenuItem

“菜单项”表

Orderitem_ids 数组和MenuItem__id__ 整数列上并获取MenuItem价格数组,但出现错误:

不支持引用其他表的相关子查询,除非它们可以解除相关,例如通过将它们转换为有效的 JOIN。

如何避免这个错误呢?

询问:

WITH menu_items AS 
( 
    SELECT
        __id__,
        price
    FROM
        `potykion.MenuItem`
)
SELECT
    *, 
    ARRAY(
        SELECT 
           price
        FROM 
           UNNEST(item_ids) AS id
        JOIN 
            menu_items 
        ON 
            id = menu_items.__id__
    ) 
FROM 
    `potykion.Order`
Run Code Online (Sandbox Code Playgroud)

Mik*_*ant 9

请尝试以下操作(BigQuery 标准 SQL)

WITH Orders AS (
  SELECT 1 AS id, ARRAY[1,2,3] AS item_ids UNION ALL 
  SELECT 2 AS id, ARRAY[4,5] AS item_ids UNION ALL 
  SELECT 3 AS id, ARRAY[1,4,6] AS item_ids 
),
MenuItems AS (
  SELECT 1 AS __id__, 1.1 AS price UNION ALL
  SELECT 2 AS __id__, 1.2 AS price UNION ALL
  SELECT 3 AS __id__, 1.3 AS price UNION ALL
  SELECT 4 AS __id__, 1.4 AS price UNION ALL
  SELECT 5 AS __id__, 1.5 AS price UNION ALL
  SELECT 6 AS __id__, 1.6 AS price UNION ALL
  SELECT 7 AS __id__, 1.7 AS price 
)
SELECT 
  *, 
  ARRAY(
    SELECT price 
    FROM UNNEST(item_ids) AS id 
    JOIN MenuItems 
    ON __id__ = id
  ) AS prices
FROM Orders  
Run Code Online (Sandbox Code Playgroud)

表订单:
命令

表菜单项:
菜单项

结果:
结果


pot*_*ion 8

在数组创建表达式中加入联接的解决方案是正确的,但它不适用于单独的表。替代解决方案是数组聚合:

WITH Orders AS (
  SELECT 1 AS id, ARRAY[1,2,3] AS item_ids UNION ALL 
  SELECT 2 AS id, ARRAY[4,5] AS item_ids UNION ALL 
  SELECT 3 AS id, ARRAY[1,4,6] AS item_ids 
),
MenuItems AS (
  SELECT 1 AS __id__, 1.1 AS price UNION ALL
  SELECT 2 AS __id__, 1.2 AS price UNION ALL
  SELECT 3 AS __id__, 1.3 AS price UNION ALL
  SELECT 4 AS __id__, 1.4 AS price UNION ALL
  SELECT 5 AS __id__, 1.5 AS price UNION ALL
  SELECT 6 AS __id__, 1.6 AS price UNION ALL
  SELECT 7 AS __id__, 1.7 AS price 
)
SELECT 
  id, ARRAY_AGG(price)
FROM Orders  
  JOIN MenuItems ON __id__ in UNNEST(item_ids)
  GROUP BY id
Run Code Online (Sandbox Code Playgroud)