查询以对照 BigQuery table 和 select 中的列检查列表中的每个元素,如果该列表中存在该项目的 none
Query to check each element in a list against a column in an BigQuery table and select a record if none of the item is present from that list
很难提出一个问题,因为我对 BigQuery/SQL 世界还很陌生。
因此,我需要检查 none 给定关键字列表(外部来源)中的项目是否存在于 table 中,它可以是此数组列表中关键字的组合。
让我试着用一个例子来解释:
假设我有一个关键字列表的外部来源:[foo, bar, foo1 bar, foobar, foo2 bar1, foo1 foobar, foo foo1 foo2, etc…]
(每个元素可以有多个 space 分隔的词)
在一个大查询 table 中,我们有一个数组类型 col,它是上述列表中一个或多个关键字的组合,这也是 space 分隔的( 理想情况下它应该是一个多元素列表,但不幸的是它只是一个元素space-分隔的关键字,但这是我现在必须忍受的数据问题):
column_name
foo
foo1 bar foobar
foobar foo2 bar1
bar foo1
baz foobar
etc
所以,从上面的例子来看:
“foo”
在列表中;
“foo1 bar”, “foobar”
在列表中;
“foobar”, “foo2 bar1”
在列表中;
“foobar”, “foo2 bar1”
在列表中。
“bar”
在列表中,但“foo”
不在列表中,或者如果你想考虑甚至“bar foo1”
不在列表中,我想select这条记录
“baz”
不在列表中,我也想select这条记录
你能帮我看看如何实现吗?
考虑以下方法
select *
from (
select column_name,
array(
select word
from unnest(split(column_name, ' ')) word
left join unnest(arr) phrase
group by word
having countif(regexp_contains(phrase, word)) = 0
) items_not_present_in_lists
from (
select *, array (
select phrase from phrases
where regexp_contains(column_name, phrase)
) arr
from your_table
)
)
where array_length(items_not_present_in_lists) > 0
如果应用于您问题中的示例数据 - 输出为
我在 testing/playing 中使用了以下虚拟数据(所以你也可以)
with your_table as (
select 'foo' column_name union all
select 'foo1 bar foobar' union all
select 'foobar foo2 bar1' union all
select 'bar foo1' union all
select 'baz foobar' union all
select 'etc'
), phrases as (
select phrase
from unnest(['foo', 'bar', 'foo1 bar', 'foobar', 'foo2 bar1', 'foo1 foobar', 'foo foo1 foo2', 'etc']) phrase
)
很难提出一个问题,因为我对 BigQuery/SQL 世界还很陌生。
因此,我需要检查 none 给定关键字列表(外部来源)中的项目是否存在于 table 中,它可以是此数组列表中关键字的组合。
让我试着用一个例子来解释:
假设我有一个关键字列表的外部来源:[foo, bar, foo1 bar, foobar, foo2 bar1, foo1 foobar, foo foo1 foo2, etc…]
(每个元素可以有多个 space 分隔的词)
在一个大查询 table 中,我们有一个数组类型 col,它是上述列表中一个或多个关键字的组合,这也是 space 分隔的( 理想情况下它应该是一个多元素列表,但不幸的是它只是一个元素space-分隔的关键字,但这是我现在必须忍受的数据问题):
column_name |
---|
foo |
foo1 bar foobar |
foobar foo2 bar1 |
bar foo1 |
baz foobar |
etc |
所以,从上面的例子来看:
“foo”
在列表中;
“foo1 bar”, “foobar”
在列表中;
“foobar”, “foo2 bar1”
在列表中;
“foobar”, “foo2 bar1”
在列表中。
“bar”
在列表中,但“foo”
不在列表中,或者如果你想考虑甚至“bar foo1”
不在列表中,我想select这条记录
“baz”
不在列表中,我也想select这条记录
你能帮我看看如何实现吗?
考虑以下方法
select *
from (
select column_name,
array(
select word
from unnest(split(column_name, ' ')) word
left join unnest(arr) phrase
group by word
having countif(regexp_contains(phrase, word)) = 0
) items_not_present_in_lists
from (
select *, array (
select phrase from phrases
where regexp_contains(column_name, phrase)
) arr
from your_table
)
)
where array_length(items_not_present_in_lists) > 0
如果应用于您问题中的示例数据 - 输出为
我在 testing/playing 中使用了以下虚拟数据(所以你也可以)
with your_table as (
select 'foo' column_name union all
select 'foo1 bar foobar' union all
select 'foobar foo2 bar1' union all
select 'bar foo1' union all
select 'baz foobar' union all
select 'etc'
), phrases as (
select phrase
from unnest(['foo', 'bar', 'foo1 bar', 'foobar', 'foo2 bar1', 'foo1 foobar', 'foo foo1 foo2', 'etc']) phrase
)