Sql 基于最相关前缀连接两个表

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 | 我想将这两个表连接起来

假设我有以下表格:

表1:

| 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;