我正在使用Google BigQuery,但遇到以下问题:
我有一张这样的表(A):
| time | request |
|------------------------|-----------------|
|2019-09-24 11:10:00 UTC | fakewebsite.com |
|2019-09-24 11:10:00 UTC | realwebsite.com |
|........................|.................|
|2019-09-24 11:10:00 UTC | foobwebsite.com |
|2019-09-24 11:10:00 UTC | barrwebsite.com |
和另一个表(B
)像这样:
| blacklist |
|---------------|
| foo.com |
| ... |
| bar.com |
我想进行查询,以获取表B的黑名单字段内的值的修改版本,如下所示:
SPLIT(NET.REG_DOMAIN(blacklist), CONCAT('.',NET.PUBLIC_SUFFIX(blacklist)))[OFFSET(0)] AS to_exclude
-这将仅从“ foo.com”返回“ foo”
然后返回表A的request
字段中的所有值,其中未找到to_exclude
。
我知道如何针对一个值执行此操作,但我不知道针对多个值执行此操作。我正在寻找类似以下内容的东西:
#standardSQL
WITH tmp_blacklist AS
(SELECT
SPLIT(NET.REG_DOMAIN(blacklist), CONCAT('.',NET.PUBLIC_SUFFIX(blacklist)))[OFFSET(0)] AS to_exclude
FROM
mydataset.B)
SELECT
request
FROM
mydataset.A
WHERE
request NOT LIKE ("%value1%", "%value2%", ..., "%valuen%") -- I can't use OR along with the NOT LIKE since the values are too many and they will change.
n values
是tmp_blacklist
表的值。
[此外,如果我没有用WITH
定义表,而是在NOT LIKE
之后定义了表,则会收到以下错误:Scalar subquery produced more than one element
,如果LIKE
仅期望一个元素,这是有意义的。但是话又说回来,那是完成了一半的工作,因为我想要的是"%value%"
,而不仅仅是表格的value
。
[现在,我在网上搜索了一种方法来做到这一点,然后我发现有人说无法做到这一点,然后有人采用LIKE
和IN
的组合进行变通,其中有人说,如果其中一个表增长到拥有大量数据(我的情况)。
最佳方法是什么?
一种方法使用not exists
:
SELECT a.request
FROM mydataset.A a
WHERE NOT EXISTS (SELECT 1
FROM tmp_blacklist bl
WHERE a.request LIKE CONCAT('%', bl.to_exclude, '%'
);
请注意,这可能很昂贵。您可能需要测试构建排除字符串,如下所示:
'value1|value2|value3'
然后使用正则表达式。