我有以下 SQL Server 查询
select
(select top 1 b2 from BB b where b.b1 = a.a1 order by b2) calc,
a1,
a2
from AA a
where a2 = 2;
我可以使用分析函数重写
select
(select b2 from
(select
row_number() over (order by b2) lfd,
b2 from BB b where b.b1 = a.a1
) as t where lfd = 1
) calc,
a1,
a2
from AA a
where a2 = 2;
但是当我将其转换为 oracle
create table AA ( a1 NUMBER(10), a2 NUMBER(10) );
insert into AA values ( 1, 1);
insert into AA values ( 1, 2);
insert into AA values ( 1, 3);
insert into AA values ( 2, 2);
create table BB ( b1 NUMBER(10), b2 NUMBER(10) );
insert into BB values ( 1, 1);
insert into BB values ( 2, 4);
insert into BB values ( 2, 5);
select * from AA;
select * from BB;
select
(select b2 from
(select
row_number() over (order by b2) lfd,
b2 from BB b where b.b1 = a.a1
) where lfd = 1
) calc,
a1,
a2
from AA a
where a2 = 2;
我收到以下错误
Error at line 5
ORA-00904: "A"."A1": invalid column name
您将首先在 Oracle 中执行连接:
您的查询的问题是,目前 Oracle 中的子查询无法从父查询中访问超过两级以上的值。
您还可以使用包含内部 SELECT 的 PL/SQL 函数。
如果这些是您正在寻找的结果:
你可以用这个得到它:
在这里,我将展示我在使用 Vincent Malgrat 的方法时得到的一些结果。
首先我了解到,当基于不同的表或顺序使用超过 1 个这样的 top 1 子查询时,我必须使用RANK()函数而不是ROW_NUMBER()函数。
其次,在使用 rank() 时存在关系问题。SQL Server 的 top 1 任意选择 rank = 1 的行之一,而使用 rank() 可以返回多于 1 行。
我认为在这些情况下使用 SQL Server top 1 是不好的设计。为了使设计正确,必须找到一些唯一约束(例如唯一索引),以防止这种歧义。
如果您想自己尝试,这里有一个 SQL Server 示例。
比较下面最后两个 select 语句的执行计划表明,Vincent Malgrat 的方法比 top 1 解决方案要好。
对 Leigh Riffel 的回答:
在以下 id 为 1 和 2 的行中,rank() 和 dense_rank 均为 1。
结果:
对 Leigh Riffel 的新回答:
这是一个示例,我无法使用您的模式进行转换。我有一张带有文章价格的表格,还有一张带有价格变化历史的表格。当价格发生变化时,一些权威想知道旧价格。
我想得到
但第二个给出
文森特马尔格拉特的方法产生了正确的结果