SQL首先选择符合条件的SQL

时间:2017-03-13 14:10:56

标签: sql oracle oracle10g

我有一个查询,我必须对表进行排序并检索匹配每个id的第一个值。

我想要实现的方案是获取表A的ID与排序表B中的第一个ID_2相匹配

我对代码略有概念。

select A.ID, A.COL1, B.COL1, B.COL2 
  from A, B
 where A.ID = B.ID
   and B.ID_2 = (select ID_2 
                   from (select ID_2 
                           from B B2 
                          where B2.ID = A.ID 
                       order by (case when B2.PRIO ...)) 
                  where rownum = 1)

这里的问题是在where子句中的select中无法访问A.ID。

我发现的另一种方法是使用分析函数

select ID, COL1, COL2
  from (select A.ID, A.COL1, B.COL2, 
               row_number() over (partition by A.ID order by (case when B.PRIO ...) row_num
          from A, B
         where A.ID = B.ID)
 where row_num = 1

这段代码的问题是我认为这不是很好的性能。

任何人都可以帮助我吗? =)

2 个答案:

答案 0 :(得分:1)

row_number()不是统计功能。它是一个分析或窗口函数。这可能是你最好的选择。我愿意:

select a.*
from A join
     (select b.*, 
             row_number() over (partition by b.ID order by (case when b.PRIO ...) as seqnum
      from b
     ) b
     on A.ID = B.ID and b.seqnum = 1;

如果您真的只想要A.ID,那么您根本不需要A。 。 。信息在B.ID中(假设它没有用于过滤)。以上简化为:

select b.id
from (select b.*, 
             row_number() over (partition by b.ID order by (case when b.PRIO ...) as seqnum
      from b
     ) b
where b.seqnum = 1;

答案 1 :(得分:0)

您不需要相关的子子查询(在Oracle中无效),也不需要分析函数。您需要汇总first/last函数。

... and b.id_2 = (select max(id_2) keep (dense_rank first order by case.....) 
                  from   b b2
                  where  b2.id = a.id
                 )     .....

即使这可能太复杂了。如果您要描述您的要求(而不仅仅是发布一些不完整的代码),社区可能会帮助您进一步简化查询。