如何在标准 SQL 的 WHERE 子句中使用 WITH 子查询作为选项列表

Posted

技术标签:

【中文标题】如何在标准 SQL 的 WHERE 子句中使用 WITH 子查询作为选项列表【英文标题】:How to use WITH subqueries as a list of options in WHERE clause in standard SQL 【发布时间】:2020-03-10 15:42:11 【问题描述】:

有什么问题

我有一个非常大的结果列表。我想根据表中最受欢迎的结果过滤我的查询,使其仅包含一小部分查询。

当我将过滤子查询放在WITH 子句中时,它不起作用。但是,如果我将它直接放在 WHERE 子句中,它确实有效。为什么?

为了清楚起见,我更喜欢第一个,但我无法让它工作。

我正在使用 StandardSQL 在 BigQuery 中工作。

示例

WITH
  most_common AS (
  SELECT
    page
  FROM
    `mydataset`
  LIMIT 
    100
)
SELECT
  *
FROM
   `mydataset`
WHERE
  page IN most_common

这里我试图获取所有结果,其中页面位于前 100 行中。

它返回以下错误: - Syntax error: Expected "(" or keyword UNNEST but got identifier "most_common" at [12:12]

但是,如果我将子查询直接放在它可以正常工作的地方。

SELECT
  *
FROM
   `mydataset`
WHERE
  page IN (
  SELECT
    page
  FROM
    `mydataset`
  LIMIT 
    100
)

我的理解有限

它说它想要 unnest,但 unnest 将数组转换为表结果作为子查询,这应该已经是一个表。

【问题讨论】:

【参考方案1】:
#standardSQL
WITH
  most_common AS (
  SELECT
    page
  FROM
    `mydataset`
  LIMIT 
    100
)
SELECT
  *
FROM
   `mydataset`
WHERE
  page IN (SELECT page FROM most_common)  

另一种选择:

#standardSQL
WITH most_common AS (
  SELECT ARRAY_AGG(page) pages FROM (
    SELECT page
    FROM `mydataset`
    LIMIT 100
  )
)
SELECT *
FROM `mydataset`, most_common
WHERE page IN UNNEST(pages)   

或稍微重构的版本

#standardSQL
WITH most_common AS (
  SELECT ARRAY_AGG(page LIMIT 100) pages 
  FROM `mydataset`
)
SELECT *
FROM `mydataset`, most_common
WHERE page IN UNNEST(pages)  

注意:ARRAY_AGG(...) 接受 ORDER BY 子句,因此您实际上可以使用此语法ARRAY_AGG(page ORDER BY some metric DESC LIMIT 100) 选择最常用的子句 显然最终版本取决于你的真实用例——但不是这个——你得到了我希望的想法

【讨论】:

【参考方案2】:

当您使用 CTE 表达式编写查询时,数据将以表格格式返回。您可以在子查询中使用 CTE 表达式来工作。

WITH MYSELECT AS (SELECT
  status
FROM
  `bigquery-public-data.austin_311.311_request`
LIMIT 100)
SELECT COUNT(*) FROM `bigquery-public-data.austin_311.311_request` WHERE status IN (SELECT DISTINCT status FROM MYSELECT);

【讨论】:

以上是关于如何在标准 SQL 的 WHERE 子句中使用 WITH 子查询作为选项列表的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 SQL Server 在 WHERE 子句之前处理 CONTAINS 子句?

SQL Where 子句详解

三.SQL WHERE 子句(where)

如何将 if 条件放在 where 子句中

如何在子查询的 WHERE 子句中使用来自 UNNEST 的多个值?

SQL WHERE 子句