Bigquery SQL SELECT WHERE 字段包含来自其他表的许多单词

Posted

技术标签:

【中文标题】Bigquery SQL SELECT WHERE 字段包含来自其他表的许多单词【英文标题】:Bigquery SQL SELECT WHERE field contains many words from other table 【发布时间】:2017-11-29 04:18:12 【问题描述】:

我有一个包含全名的学生信息表和一个名字列表。

full_names               first_names  
---------------         -------------
john adam smith          john
jane anna doe            jane
michael brown            bob

我想选择全名包含名列表中的任何一个的学生。例如,John Adam Smith 包含单词john,我想选择该行。 Michael Brown 与任何名称都不匹配,所以我不想要它。

我可以这样做,但输入 300 多个名字会效率低下

SELECT names
FROM full_names
WHERE names CONTAIN 'john' 
  OR names CONTAIN 'jane'
  OR names CONTAIN 'bob'
...
(300 more rows)

我的尝试 - 将名称列表放入第二个表 first_names,并尝试从第一个表中选择第二个表中的名称。

SELECT names
FROM full_names 
WHERE names CONTAINS 
    (SELECT names
    FROM first_names);

但是,我得到了错误:

Error: ELEMENT can only be applied to result with 0 or 1 row.

有没有更好的方法?

【问题讨论】:

【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
SELECT full_name
FROM `project.dataset.full_names` a
CROSS JOIN `project.dataset.first_names` b 
GROUP BY full_name
HAVING MAX(REGEXP_CONTAINS(full_name, name))   

您可以使用以下问题中的虚拟数据测试/玩上述内容

#standardSQL
WITH `full_names` AS (
  SELECT 'john adam smith' full_name UNION ALL
  SELECT 'jane anna doe' UNION ALL
  SELECT 'michael brown' 
), `first_names` AS (
  SELECT 'john' name UNION ALL
  SELECT 'jane' UNION ALL
  SELECT 'bob' 
)
SELECT full_name
FROM `full_names` a
CROSS JOIN `first_names` b 
GROUP BY full_name
HAVING MAX(REGEXP_CONTAINS(full_name, name))

结果是

full_name    
---------
john adam smith  
jane anna doe    

更多选项:

#standardSQL
SELECT DISTINCT full_name
FROM `project.dataset.full_names` a
JOIN `project.dataset.first_names` b 
ON full_name LIKE CONCAT('%', name, '%')  

SELECT DISTINCT full_name
FROM `project.dataset.full_names`, UNNEST(SPLIT(full_name, ' ')) part
JOIN `project.dataset.first_names` 
ON part = name

【讨论】:

谢谢米哈伊尔!样品工作正常,我感谢您的详尽解释。不幸的是,它似乎无法在我的完整数据集上运行,因为我必须先升级我的支付层。如果不是太麻烦的话,有没有办法让这个查询变小呢?再次感谢您的帮助! 你到底有什么问题?任何错误信息?请澄清。计费取决于查询中涉及的数据量 - 因此您应该只使用需要使用的列以最大限度地降低成本 “错误:查询超出了第 1 层的资源限制。需要 2006 层或更高级别。” -- 我有 300 个名字和 2700 万个全名。我的 BQ 免费套餐中还有 300 美元的积分,所以我不确定为什么这个查询没有通过。编辑:是的,我已经只使用我需要最小化成本的列。 尝试使用 LIKE 选项而不是 REGEXP_CONTAINS。让我知道是否仍然 resources exceeded ... 错误 没有问题,感谢您成为本网站的 bigquery 英雄。实际上,您之前已经回答了我的另一个问题。谢谢!【参考方案2】:

试试这个:

SELECT names
FROM 
full_names a
inner join
first_names b
on a.names like CONCAT('%', b.names, '%') ;

如有任何疑问,请告诉我。

【讨论】:

谢谢,但这给了我像“john”这样的行,但忽略了像“john adam smith”这样的行。我还想包含部分匹配目标的行,而不仅仅是那些完全匹配目标的行。 @angsty_robot 现在试试!【参考方案3】:

未经测试,但试试这个:列名是根据快照中的列

 Select * from full_names
    where  first_names IN
    ( Select full_names from full_names)

【讨论】:

以上是关于Bigquery SQL SELECT WHERE 字段包含来自其他表的许多单词的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Bigquery Legacy SQL 中创建真正的函数

BigQuery 错误:遇到““WHERE”“WHERE”“[关闭]

是否可以在 Union All BigQuery SQL 中让 where 子句引用另一个 where 子句?

BigQuery SQL Select 返回键值对而不是两个单独的列

BigQuery 标准 SQL - 删除多个表

bigquery 分区表的分区修剪