Sql 基于最相关前缀连接两个表
假设我有以下表格: 表1:Sql 基于最相关前缀连接两个表,sql,google-bigquery,Sql,Google Bigquery,假设我有以下表格: 表1: | url | value | | google.com | 1 | | google.com/s1 | 2 | 表2: | item_url | item_value | | google.com/example | 3 | | google.com/s1/example | 4 | 我想将这两个表连接起来
| url | value |
| google.com | 1 |
| google.com/s1 | 2 |
表2:
| item_url | item_value |
| google.com/example | 3 |
| google.com/s1/example | 4 |
我想将这两个表连接起来,以便在t1中将具有的项与其对应的URL连接起来,问题在于这种简单的方法:
select * from t1,t2 where STARTS_WITH(t2.item_url, t1.url)
将导致:google.com/s1/example与第一个表中的两个值合并。是否有一种很好的干净方式来连接表,以便选择最“特定”(最长前缀?)的表
我需要的预期输出是:
| item_url | url | value
| google.com/example | google.com | 1
| google.com/s1/example | google.com/s1 | 2
谢谢。使用
ON
子句中的等操作符和按table1.url、table1.value分组,加入表
然后您需要最小的表2。结果中的项目url
:
select min(t2.item_url) item_url, t1.url, t1.value
from table1 t1 inner join table2 t2
on t2.item_url like concat(t1.url, '%')
group by t1.url, t1.value
请参阅。
结果:
你想要最长的比赛。在BigQuery中,一种方法使用聚合:
with t1 as (
select 'google.com' as url, 1 as value union all
select 'google.com/s1', 2
),
t2 as (
select 'google.com/example' as item_url, 3 as item_value union all
select 'google.com/s1/example', 4
)
select t2.item_url, t2.item_value, array_agg(t1 order by length(t1.url) desc limit 1)[offset(0)].*
from t1 JOIN
t2
ON t2.item_url like concat(t1.url, '%')
group by t2.item_url, t2.item_value;
更传统的方法是使用行数()
也可以使用相关子查询:
SELECT t2.*,
(SELECT t1
FROM t1
WHERE t2.item_url LIKE CONCAT(t1.url, '%')
ORDER BY LENGTH(t1.url) DESC
LIMIT 1
).*
FROM t2;
请注意,这些示例返回t1
中的所有列,而不仅仅是值。当然,如果您愿意,您可以调整它们,使其只返回一列。您是否可以指导我们使用手册中的函数访问MySQL的STARTS_。这对我来说是新的。对于google.com
来说,哪一个是最“具体”(最长的前缀?)?发布您的预期结果。它实际上与MySQL无关。没有注意到标记。还添加了预期的输出
SELECT t12.* EXCEPT (seqnum)
FROM (SELECT t2.*, t1.*,
ROW_NUMBER() OVER (PARTITION BY t2.item_url, t2.item_value order by length(t1.url) desc) as seqnum
from t1 JOIN
t2
ON t2.item_url like concat(t1.url, '%')
) t12
WHERE seqnum = 1;
SELECT t2.*,
(SELECT t1
FROM t1
WHERE t2.item_url LIKE CONCAT(t1.url, '%')
ORDER BY LENGTH(t1.url) DESC
LIMIT 1
).*
FROM t2;