SQL:如何限制第一个找到的行的连接?

标签 sql oracle join greatest-n-per-group

如何在两个表之间建立连接,但仅限于满足连接条件的第一行?

在这个简单的示例中,我想为 table_A 中的每一行获取 table_B 中满足条件的第一行:

select table_A.id, table_A.name, table_B.city 
from table_A join table_B 
on table_A.id = table_B.id2
where ..

table_A (id, name)
1, John
2, Marc

table_B (id2, city)
1, New York
1, Toronto
2, Boston

The output would be:
1, John, New York
2, Marc, Boston

可能Oracle提供了这样的功能(性能是一个问题)。

最佳答案

这里的关键词是首先。您可以使用解析函数FIRST_VALUE或聚合构造FIRST .
对于 FIRSTLAST性能绝不会比同等产品更差,而且常常更好 FIRST_VALUELAST_VALUE构造是因为我们没有多余的窗口排序,因此执行成本较低:

select table_A.id, table_A.name, firstFromB.city 
from table_A 
join (
    select table_B.id2, max(table_B.city) keep (dense_rank first order by table_B.city) city
    from table_b
    group by table_B.id2
    ) firstFromB on firstFromB.id2 = table_A.id 
where 1=1 /* some conditions here */
;

自 12c 引入运算符 LATERAL ,以及CROSS/OUTER APPLY连接,使得可以在 JOIN 的右侧使用相关子查询子句:

select table_A.id, table_A.name, firstFromB.city 
from table_A 
cross apply (
    select max(table_B.city) keep (dense_rank first order by table_B.city) city
    from table_b
    where table_B.id2 = table_A.id 
    ) firstFromB
where 1=1 /* some conditions here */
;

关于SQL:如何限制第一个找到的行的连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35255271/

相关文章:

sql - 如何存储变量字段?

sql - oracle 批量插入

sql - MySQL Select 语句 - 两个表,根据其他表的计数对一个表进行排序

java - 为什么 JPA join 返回太多结果?

MySQL 限制 LEFT JOIN 加入后的子查询

mysql - 如何匹配一列中的所有行

asp.net - 数据库连接池大小合理限制?

.net - 如何使用 Oracle、.Net、Winform、Windows Vista 和 XP

mysql - 如何使选择查询在具有 4 列(sno、sname、job、dept)、有 10 条记录的简单表上运行超过 30 分钟?

sql - 在 Hive 中创建具有当前时间戳(以纳秒为单位)的新列