2017-03-13 119 views
0

我有一个查询,我必须对表格进行排序并检索与每个id匹配的第一个值。SQL选择第一个匹配标准

,我想实现的方案是让表A的,从排序表B

我的代码略有概念第一ID_2匹配的ID。

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子句中无法访问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 

的问题与此代码是我认为这是不好的表现明智的。

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

+0

统计功能?那是什么意思? – mathguy

+0

请显示样本表数据和预期输出。 “不好的表现”是什么意思?请阅读[问]一些提示。 – OldProgrammer

+1

@johngo'我觉得这不是很好的表现'......你为什么这么想?您是否尝试针对您的数据运行这两个查询?你比较执行路径吗? – Boneist

回答

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

连接可以在那里以确保只有表b中具有表a中的id的行被选中。 – Boneist

+0

嗨,谢谢你的回复,正如Boneist所说的,表A是需要的,因为我只需要显示表A中具有ID的行。我将尝试首先检查执行路径,谢谢你的答案= ) –

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 
       )  ..... 

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

相关问题