Dienstag, Januar 21, 2020

Oracle geschachtelte korrelierte Unterabfrage problem

Betrachten Tabelle1 und Tabelle2 mit einer eins-zu-viele-Beziehung („Tabelle1“ ist die master-Tabelle und Tabelle2 ist der detail-Tabelle). Ich möchte Datensätze aus Tabelle1, wo einige Wert (‚XXX‘) ist der Wert des letzten Datensatzes in Tabelle2 der detail-Datensätze korrelierten auf table1. Was ich tun will, ist dies:

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)

Aber, da der Verweis auf Tabelle 1 (t1) in die korrelierte Unterabfrage ist zwei Ebenen tief, es öffnet sich mit einem Oracle-Fehler (ungültige id t1). Ich muss in der Lage sein, neu zu schreiben, aber die einzige Einschränkung ist, dass nur die where-Klausel geändert werden können (d.h. die anfängliche wählen Sie und aus muss unverändert bleiben). Kann es getan werden?

InformationsquelleAutor GriffeyDog | 2011-03-15

4 Kommentare

  1. 6

    Hier ist ein anderer analytischer Ansatz:

    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)

    Und hier ist die gleiche Idee mit einer ranking-Funktion:

    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)
    • Ich werde diese mal versuchen. Ich werde schauen Sie in später. Danke.
    • Danke Dave, jedes Beispiel funktioniert Super. Ich dachte, dies könnte getan werden, mit Video-Analyse-Funktionen, war sich aber nicht ganz sicher, wie Sie es schreiben.
    • Was ist, wenn ich wollte, die zweite, die Dritte und die nächsten Ergebnisse mit order by-Klausel? Ist es möglich, mit diesem Ansatz?
    • Herausgefunden, wie es mit NTH_VALUE() anstelle von FIRST_VALUE() oder LAST_VALUE(). Es funktionierte wie ein Charme.
  2. 3

    könnten Sie Analysen hier: join Tabelle1 in Tabelle2, die neuesten Tabelle2 Datensatz für jedes element in „Tabelle1“, und stellen Sie sicher, dass diese jüngste element hat den Wert ‚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'

    Update: Ohne änderung an der top-level-WÄHLEN Sie, Sie schreiben, könnte eine Abfrage wie diese:

    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)

    Grundsätzlich nur an (SEMI-JOIN) Zeilen aus Tabelle2, die die jüngsten für jede fk_id

    • Ich will nicht zu ändern, die top-level-select oder from-Klauseln.
    • das sieht ziemlich willkürlich :p
    • Es ist, weil, wie unsere Anwendung ist mit der Erstellung der Abfrage. Die select-und from sind mehr oder weniger konstant, und dann die wo enthält verschiedene Filter, die wir anwenden, um die Daten.
  3. -1

    Versuchen Sie dies:

    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)
    )
    • Nur wenn date_col ist einzigartig, das scheint unwahrscheinlich.
  4. -1

    Nicht das tun, was du suchst?

    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)
                    )
    • Nur wenn date_col ist einzigartig, das scheint unwahrscheinlich.

Kostenlose Online-Tests