2017-03-13 137 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 
       )  ..... 

即使這可能太複雜了。如果您要描述您的需求(而不是僅僅發佈一些不完整的代碼),社區可以幫助您進一步簡化查詢。

相關問題