2011-03-15 70 views
5

考慮Table 1和Table與一對多的關係(表1是主表和表2是詳細表)。我想從table1獲取記錄,其中某些值('XXX')是與table1相關的詳細記錄的表2中最近記錄的值。我想這樣做是:甲骨文嵌套相關子問題

select t1.pk_id 
    from table1 t1 
where 'XXX' = (select a_col 
        from ( select a_col 
          from table2 t2 
          where t2.fk_id = t1.pk_id 
         order by t2.date_col desc) 
       where rownum = 1) 

但是,由於在相關子查詢的參照表1(T1)是兩個層次深,它與Oracle錯誤(無效ID T1)彈出。我需要能夠重寫這一點,但有一點需要注意的是,只有where子句可能會改變(即最初的select和from必須保持不變)。可以做到嗎?

回答

6

這裏有一個不同的分析方法行:

select t1.pk_id 
    from table1 t1 
where 'XXX' = (select distinct first_value(t2.a_col) 
            over (order by t2.date_col desc) 
        from table2 t2 
        where t2.fk_id = t1.pk_id) 

這裏是一個使用排序功能相同的想法:

select t1.pk_id 
    from table1 t1 
where 'XXX' = (select max(t2.a_col) keep 
          (dense_rank first order by t2.date_col desc) 
        from table2 t2 
        where t2.fk_id = t1.pk_id) 
+0

我會試試這些。我稍後再回來查看。謝謝。 – GriffeyDog 2011-03-15 17:15:31

+0

感謝戴夫,每個例子都很棒。我認爲這可以通過分析函數來完成,但不太確定如何編寫它。 – GriffeyDog 2011-03-15 19:05:10

+0

如果我想要按順序排列的第二,第三和下一個結果怎麼辦?使用這種方法可能嗎? – Sawd 2015-09-24 17:40:28

-1

試試這個:

select t1.pk_id 
from table1 t1 
where 'XXX' = 
(select a_col 
from table2 t2       
where t2.fk_id = t1.pk_id       
and t2.date_col = 
    (select max(t3.date_col) 
    from table2 t3 
    where t3.fk_id = t2.fk_id) 
) 
+0

只有date_col上是獨一無二的,這似乎不太可能。 – Mark 2017-08-24 12:16:33

-1

這是否你在找什麼?

select t1.pk_id 
    from table1 t1 
where 'XXX' = ( select a_col 
        from table2 t2 
        where t2.fk_id = t1.pk_id 
        t2.date_col = (select max(date_col) from table2 where fk_id = t1.pk_id) 
       ) 
+0

只有在date_col是唯一的時候,這似乎不大可能。 – Mark 2017-08-24 12:16:27

3

,你可以在這裏使用的分析:加入表1至表2,利用最新表2記錄在表1的每個元素和驗證這最近的元素有「XXX」的值:

SELECT * 
    FROM (SELECT t1.*, 
       t2.a_col, 
       row_number() over (PARTITION BY t1.pk 
            ORDER BY t2.date_col DESC) rnk 
      FROM table1 t1 
      JOIN table2 t2 ON t2.fk_id = t1.pk_id) 
WHERE rnk = 1 
    AND a_col = 'XXX' 

更新:無需修改頂級SELECT,你可以寫這樣的查詢:

SELECT t1.pk_id 
    FROM table1 t1 
WHERE 'XXX' = 
     (SELECT a_col 
      FROM (SELECT a_col, 
         t2_in.fk_id, 
         row_number() over(PARTITION BY t2_in.fk_id 
             ORDER BY t2_in.date_col DESC) rnk 
        FROM table2 t2_in) t2 
     WHERE rnk = 1 
      AND t2.fk_id = t1.pk_id) 

基本上你只能加入(SEMI-JOIN)從表2是最近每個fk_id

+0

我不想更改頂級選擇或從子句。 – GriffeyDog 2011-03-15 17:16:07

+0

@GriffeyDog:這看起來很隨意的:P – 2011-03-15 17:22:27

+0

這是因爲我們的應用程序是如何構建的查詢。 select和from或多或少是常量,然後where包含我們應用於數據的各種過濾器。 – GriffeyDog 2011-03-15 18:46:38