如何在标准 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 子句?