【问题标题】:BigQuery: Correlated subqueries that reference other tables are not supported unless they can be de-correlatedBigQuery:不支持引用其他表的相关子查询,除非它们可以去相关
【发布时间】:2020-04-08 16:37:42
【问题描述】:

当我在真实表上运行查询时出现错误:

Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN

这是我正在运行的确切查询:

SELECT
CASE WHEN addresses LIKE '%,%'
THEN
(
SELECT STRING_AGG(DISTINCT address) addresses
FROM VW_CLEAN.TABLE_1
WHERE member_id = el.member_id
AND eligible_month < el.eligible_month
GROUP BY member_id, eligible_month
ORDER BY eligible_month DESC 
LIMIT 1
) 
END AS address,
eligible_month, 
member_id
FROM
(
    SELECT STRING_AGG(DISTINCT address) addresses, eligible_month, member_id FROM
    (
        SELECT DISTINCT address, eligible_month, member_id
        FROM VW_CLEAN.TABLE_1
        UNION ALL
        SELECT DISTINCT address, eligible_month, member_id
        FROM VW_CLEAN.TABLE_2
    )
    GROUP BY eligible_month, member_id
) el
WHERE member_id IS NOT NULL
AND eligible_month IS NOT NULL

但是当我使用“WITH AS”为测试数据准备相同的查询时,它运行时没有错误。

#standardSQL
WITH table_1 AS (
  SELECT "201905" AS month, "11111" AS member, "123" AS address
  UNION ALL
  SELECT "201903" AS month, "11111" AS member, "234" AS address
  UNION ALL
  SELECT "201902" AS month, "11111" AS member, "345" AS address
  UNION ALL
  SELECT "201902" AS month, "22222" AS member, "456" AS address
  UNION ALL
  SELECT "201901" AS month, "22222" AS member, "567" AS address
),
table_2 AS (
  SELECT "201904" AS month, "11111" AS member, "678" AS address
)

SELECT 
a.member,
a.month,
(
  SELECT STRING_AGG(address) address
  FROM table_1
  WHERE member = a.member
  AND month < a.month
  GROUP BY member, month
  ORDER BY month DESC 
  LIMIT 1
) AS previous_address
FROM
(
    SELECT STRING_AGG(address) address, month, member
    FROM
    (
        SELECT month, member, address
        FROM table_1
        UNION ALL
        SELECT month, member, address
        FROM table_2
    )
    GROUP BY month, member
    HAVING member = '11111' AND month = '201905'
) a

那么真实表和使用“WITH AS”创建的表有什么区别?

编辑器需要更多的文字来保存描述,所以我添加了TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT文字文字文字文字文字文字文字文字文字

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    我不知道您的问题的确切答案,但是,我可以说您的查询不是最佳做法之一。

    我想了解更多关于您的 table1 和 table2 的信息,以便更好地查询,但现在,我将把它当作一个单独的表来获取成员的先前地址。

    因此您可以使用窗口函数来获取用户的先前值。 我为您准备了一个示例查询,如果您能提供有关您的表格和用途的更多详细信息,我可以做得更好。

    WITH table_1 AS (
      SELECT "201905" AS month, "11111" AS member, "123" AS address
      UNION ALL
      SELECT "201903" AS month, "11111" AS member, "234" AS address
      UNION ALL
      SELECT "201902" AS month, "11111" AS member, "345" AS address
      UNION ALL
      SELECT "201902" AS month, "22222" AS member, "456" AS address
      UNION ALL
      SELECT "201901" AS month, "22222" AS member, "567" AS address
    ),
    table_2 AS (
      SELECT "201904" AS month, "11111" AS member, "678" AS address
    )
    SELECT 
      *,
      lag(address) over (partition by member order by month) previous_address,
      last_value(t1_address ignore nulls) over (partition by member order by month rows between unbounded preceding and 1 preceding) as previous_t1_address
    FROM 
    (
        SELECT month, member, address, address as t1_address
        FROM table_1
        UNION ALL
        SELECT month, member, address, null
        FROM table_2
    );
    

    【讨论】:

    • 我已经在描述中添加了我正在运行的确切查询。请帮忙看看,谢谢。
    • 问题是您不应该在 BigQuery 中使用相关查询。这是一个不好的做法。 BigQuery 不是为这种用途而设计的。此外,对于您的用例,即使在其他数据库引擎中,相关查询也不是最好的方法。有窗口函数可以解决您的问题,您应该使用它们。为什么不想使用上面的查询?它已经按预期工作,如果没有,我们可以修复它。只需为您的问题提供输入和输出数据。
    • “el”子查询的结果可以是:addresses:address1,address2 member:11111qualified_month:201906 所以当我在地址中得到像“%,%”这样的结果时,我想取地址从上个月开始。但是上个月并不总是201905,甚至可能是201802。我们假设这个成员之前的记录是:addresses:address3 member:11111qualified_month:201802 所以整个查询的输出应该是:addresses:address3 member: 11111 合格_月:201906
    • 你试过我的查询了吗?它在哪里失败?它完全符合您的要求。
    【解决方案2】:

    根据文档。

    FROM 子句别名对同一 FROM 中的子查询不可见 条款。 FROM 子句中的子查询不能包含相关 在同一个 FROM 子句中引用其他表。

    在您的情况下,您使用字段 el.member_idel.eligible_month 并根据上述消息,表格 el 对子查询不可见。

    here 中,您可以找到更多关于无效关联子查询的示例。

    但是,最佳实践应该是 WITH 语句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多