Sql bigquery中的条件联接
我有两张桌子 表1是一列整数 表2有三列:开始整数、结束整数、数据 简单的查询是将整数列与其中的数据连接起来Sql bigquery中的条件联接,sql,join,google-bigquery,Sql,Join,Google Bigquery,我有两张桌子 表1是一列整数 表2有三列:开始整数、结束整数、数据 简单的查询是将整数列与其中的数据连接起来 integer >= start_integer AND integer <= end_integer 但BigQuery似乎只支持带有=条件的连接 这可以通过交叉连接来实现,但是BigQuery抱怨我的表太大了。交叉连接无效 如何在BigQuery的SQL限制内完成此连接任务 下面是我的BigQuery SQL: SELECT tbl1.integer, tbl2.d
integer >= start_integer AND integer <= end_integer
但BigQuery似乎只支持带有=条件的连接
这可以通过交叉连接来实现,但是BigQuery抱怨我的表太大了。交叉连接无效
如何在BigQuery的SQL限制内完成此连接任务
下面是我的BigQuery SQL:
SELECT tbl1.integer, tbl2.data
FROM bq:data.tbl1
CROSS JOIN bq:data.tbl2
WHERE tbl1.integer BETWEEN tbl2.start_integer AND tbl2.end_integer;
返回错误:
错误:4.1-4.132:联接运算符的右侧表必须是一个小表。如果左侧表较小,则切换表;如果两个表都大于中所述的最大值,则使用JOIN EACH
您是否尝试了以下查询:
SELECT tbl1.integer, tbl2.data
FROM bq:data.tbl1
JOIN EACH bq:data.tbl2
ON tbl1.integer >= tbl2.start_integer AND tbl1.integer <= tbl2.end_integer;
选择tbl1.integer,tbl2.data
来自bq:data.tbl1
加入每个bq:data.tbl2
在tbl1.integer>=tbl2.start\u integer和tbl1.integer上,BigQuery不支持右侧表上的交叉联接。好消息(2016)!BigQuery现在确实支持不平等联接-请确保取消选中“使用遗留SQL选项”
查询示例:
SELECT *
FROM (
SELECT 1 x
) a JOIN (
SELECT 2 y
) b
ON a.x<b.y
使用标准SQL:
1 2
- 文件:
- 讨论:
只是简单地介绍一下我是如何解决这个问题的——有点粗糙,但这是我发现的最快的方法,可以很好地扩展
输入表如下所示:
{
"ip": "130.211.149.140",
"ip_int": "2194904460",
"ip_part1": "130",
"ip_part2": "211",
"ip_part3": "149",
"ip_part4": "140",
"num_requests": "6811"
}
查找表如下所示:
{
"de_ip_key": "DE18_92.66.156.93_92.66.156.112",
"ip_key": "92.66.156.93_92.66.156.112",
"ip_from_int": "1547869277",
"ip_to_int": "1547869296",
"ip_from": "92.66.156.93",
"ip_to": "92.66.156.112",
"naics_code": "518210",
"ip_from_part1": "92",
"ip_from_part2": "66",
"ip_from_part3": "156",
"ip_from_part4": "93",
"ip_to_part1": "92",
"ip_to_part2": "66",
"ip_to_part3": "156",
"ip_to_part4": "112"
}
因此,使用ip地址的第1部分和第2部分进行连接,以减少搜索空间(我的查找表中的“从”和“到”范围的范围往往不会宽到有不同的第1部分和第2部分-如果这样,这种方法会失败)
因此,它基本上会吹出数据(通过ip地址的第1部分和第2部分上的相等连接以及ip_from和ip_to addresses),然后使用if-between语句在组上减少数据(这样做而不是where条件可以确保获得正确的左外部联接,以便还可以查看哪些记录已处理,但在查找表中没有任何信息)
Defo不是最漂亮的,可能还有一种或两种以上的方法来优化它,但现在正在为我工作,在10-20秒内根据16M记录的查找表查找500K输入ip地址。您的中间需要移动到何处,并使用交叉连接。根据文档,交叉连接操作可以返回大量数据。如果交叉查询不起作用,请发布交叉查询。交叉连接查询和错误发布中没有每个。数据的性质是什么?根据问题的性质,可能有一个很好的解决方法。IP地址列表和与一系列IP地址关联的数据。我也有这个确切的问题。可以使用UDF将每个ip映射到正确表中的一个范围?BigQuery不支持连接中的等式。2016年更新:新的BigQuery SQL确实支持连接中的不等式-取消选中“遗留SQL”。)哦,太好了,只是花了一天的时间试图解决R中的数据表的问题。迫不及待地想查看它。
{
"ip": "130.211.149.140",
"ip_int": "2194904460",
"ip_part1": "130",
"ip_part2": "211",
"ip_part3": "149",
"ip_part4": "140",
"num_requests": "6811"
}
{
"de_ip_key": "DE18_92.66.156.93_92.66.156.112",
"ip_key": "92.66.156.93_92.66.156.112",
"ip_from_int": "1547869277",
"ip_to_int": "1547869296",
"ip_from": "92.66.156.93",
"ip_to": "92.66.156.112",
"naics_code": "518210",
"ip_from_part1": "92",
"ip_from_part2": "66",
"ip_from_part3": "156",
"ip_from_part4": "93",
"ip_to_part1": "92",
"ip_to_part2": "66",
"ip_to_part3": "156",
"ip_to_part4": "112"
}
select
ip,
ip_int,
-- pick first info from de
first(ip_key) as ip_key,
first(de_ip_key) as de_ip_key,
first(naics_code) as naics_code
from
(
select
ip as ip,
ip_int as ip_int,
ip_key as ip_key,
de_ip_key as de_ip_key,
naics_code as naics_code,
from
-- join based on part 1 and 2 of ip from range
(
select
input.ip as ip,
input.ip_int as ip_int,
if(input.ip_int between de.ip_from_int and de.ip_to_int,de.ip_key,null) as ip_key,
if(input.ip_int between de.ip_from_int and de.ip_to_int,de.de_ip_key,null) as de_ip_key,
if(input.ip_int between de.ip_from_int and de.ip_to_int,de.naics_code,null) as naics_code,
from
[ip.lookup_input_tbl] input
left outer join each
[digital_element.data_naics_code] de
on
input.ip_part1=de.ip_from_part1
and
input.ip_part2=de.ip_from_part2
group by 1,2,3,4,5
),
-- join based on part 1 and 2 of ip to range
(
select
input.ip as ip,
input.ip_int as ip_int,
if(input.ip_int between de.ip_from_int and de.ip_to_int,de.ip_key,null) as ip_key,
if(input.ip_int between de.ip_from_int and de.ip_to_int,de.de_ip_key,null) as de_ip_key,
if(input.ip_int between de.ip_from_int and de.ip_to_int,de.naics_code,null) as naics_code,
from
[ip.lookup_input_tbl] input
left outer join each
[digital_element.data_naics_code] de
on
input.ip_part1=de.ip_to_part1
and
input.ip_part2=de.ip_to_part2
group by 1,2,3,4,5
),
group by 1,2,3,4,5
-- order so null records from either join go to bottom and get left behind on the first group by
order by ip_int,ip_key desc
)
group by 1,2