【问题标题】:BigQuery referencing subquery under WITH clause in WHERE clauseBigQuery 在 WHERE 子句中的 WITH 子句下引用子查询
【发布时间】:2020-04-15 19:30:03
【问题描述】:

基本上我想将 WITH 子句中定义的 ListOfIds 子查询直接引用为单列表。例如,我想实现以下目标。

WITH
  ListOfIds AS (
  SELECT
    Id
  FROM
    ...)
SELECT
  *
FROM
  ...
WHERE
  Id IN ListOfIds

上面的语法导致错误ListOfIds is not defined on line Id IN ListOfIds

到目前为止,我能达到的最接近的是以下,我不喜欢它,因为它有些复杂和冗余的语法。

WITH
  ListOfIds AS (
  SELECT
    Id
  FROM
    ...)
SELECT
  *
FROM
  ...
WHERE
  Id IN (
  SELECT
    Id
  FROM
    ListOfIds)

提前感谢您的任何帮助或建议。

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    首先是一个注释。 你可能不想这样做。

    CTE(WITH 查询)对于通常编码的人来说有点违反直觉,因为它感觉像是一个变量,但事实并非如此。 实际发生的情况是 you run the query many times 对其进行评估,导致性能不佳并额外花费 $$。

    我建议您将其替换为简单的 JOIN,它会实现相同的效果,并且通常会更好。

    基本上你的查询是这样的:

    WITH list_of_ids AS (
       SELECT id FROM table_with_ids
    )
    
    SELECT main_table.*
    FROM main_table 
    JOIN list_of_ids
       ON main_table.id = list_of_ids.id
    

    我认为它的语法非常简洁,可以解决您的问题。 让我知道是否有我遗漏的东西,我可以补充。

    【讨论】:

      【解决方案2】:

      除了Francesco所说的,如果你真的想把它当成一个变量,其实也是可以的,而且可能根本不贵。

      DECLARE ListOfIds ARRAY<INT64> DEFAULT (SELECT ARRAY_AGG(Id) FROM ...);
      
      SELECT
        *
      FROM
        ...
      WHERE
        Id IN UNNEST(ListOfIds)
      

      【讨论】:

        【解决方案3】:

        以下是 BigQuery 标准 SQL

        #standardSQL
        WITH ListOfIds AS (
          SELECT ARRAY_AGG(Id) ids
          FROM ...
        )
        SELECT * EXCEPT(ids) 
        FROM ...
        ,ListOfIds
        WHERE id IN UNNEST(ListOfIds.ids)   
        

        [Super] 上面测试/玩的简化示例是:

        #standardSQL
        WITH ListOfIds AS (
          SELECT ARRAY_AGG(Id) ids
          FROM UNNEST([1, 2, 3, 4, 5]) id
        )
        SELECT * EXCEPT(ids) 
        FROM UNNEST([1, 3, 5, 7, 9]) id
        ,ListOfIds
        WHERE id IN UNNEST(ids)   
        

        有输出

        Row id   
        1   1    
        2   3    
        3   5    
        

        【讨论】:

        • 忘了提 - 除非你真的有充分的理由来回答你的问题 - 我会推荐 Francesco-Paolo-Galletta 推荐的 JOIN。我这么说的原因是我可以看到您最初询问的唯一原因是减少冗长的查询,以免与所有 JOIN 和 ON 子句等混淆。如果您有不同的原因 - 请分享您的用例
        猜你喜欢
        • 1970-01-01
        • 2021-05-05
        • 1970-01-01
        • 2021-11-16
        • 1970-01-01
        • 2012-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多