2017-01-06 4 views
0

Ich arbeite mit einer Oracle 12-Datenbank, die Mainframe-Daten darstellt. Hier ist meine Frage.Oracle Join mit zwei möglichen Spalte Daten

Wir haben zwei Hierarchieebenen, "System" und "Prin". Stellen Sie sich sie als Staat und Grafschaft in den USA vor. Manchmal erstellt ein Client alles auf Systemebene, und alle untergeordneten Elemente beziehen sich immer auf die Systemkonfiguration. Andere Clients, die auf Prin-Ebene erstellt wurden, und die untergeordneten Prints müssen zuerst die PRIN-Level-Daten für die Konfiguration prüfen, wenn prin nicht in der Tabelle enthalten ist, dann wird standardmäßig die Konfiguration auf Systemebene verwendet. Ziemlich einfach.

Hier ist, wo ich den Tisch nicht zur Arbeit kommen kann. Ein einzelner Client kann einige Systeme auf Systemebene und andere auf der Prinzebene erstellen. Wie kann ich dynamisch beitreten, wenn ich nicht sicher bin, welche Konfiguration der Client in diesem speziellen prin verwendet?

Beispiel:

WITH tbl as (
select 80 SYSTEM, 0 PRIN, 2 DATA from dual 
union 
select 80 , 1 , 3 from dual 
union 
select 80 , 2 , 4 from dual 
) 

jetzt, wenn ich befindet sich ein Element haben in System 80 prin 3 ... es wird die 0 prin Daten benötigen, da 0 das "System" config bezeichnet.

also wenn ich prin 1 habe, möchte ich Daten "3". wenn ich prin 2, data "4" habe, wenn ich prin 8 habe, will ich data "2" weil es keine prin 8 config built gibt.

Sehen Sie, wo ich versuche zu bekommen? So

wenn ich das tue

select * 
from tbl t 
inner join tbl2 tt on t.sys = tt.sys and prin = ????? 

, wie soll ich sagen "wenn prin in Tabl gebaut wird, Verwendung prin, sonst prin default = 0"

Ich weiß, das ist eine schlecht angegeben Frage. Also bitte fragen Sie genauer und ich werde versuchen, schnell zu antworten. Dies betrifft mehrere Tabellen.

+0

Willkommen an Bord.Ich denke, dass Sie besser Ihre Frage/Code unter Verwendung Ihres Zustand- und Grafschaftbeispiels als etwas wiederholen können, mit dem wir uns alle leicht verbinden können. Ich denke, dass Ihr Beispielcode zu viele domänenspezifische Informationen enthält, so dass wir ein gewisses Maß an Wissen über Ihr spezielles System und Ihre Branche benötigen. – Caltor

Antwort

0

ziemlich hässlich, aber dann ist so das Datenmodell ...

with 
    tbl (s, prim, val) as (
     select 80, 0, 2 from dual union all 
     select 80, 1, 3 from dual union all 
     select 80, 2, 4 from dual 
    ), 
    inputs (s, prim) as (
     select 80, 1 from dual union all 
     select 80, 5 from dual 
    ) 
select t.s, i.prim i_prim, t.prim tbl_prim, t.val 
from tbl t join inputs i 
      on t.s = i.s 
      and 
      ( t.prim = i.prim 
       or t.prim = 0 
       and not exists (select * from tbl 
           where s = i.s and prim = i.prim)) 
; 

    S  I_PRIM TBL_PRIM  VAL 
---- ---------- ---------- ---------- 
    80   5   0   2 
    80   1   1   3 

2 rows selected. 
+0

Dies funktionierte perfekt und hatte keinen Einfluss auf die Abfrageleistung um mehr als 5-10 Sekunden . Vielen Dank. – Bsbal18

+0

^^^ zu addieren, waren die Tabellen ungefähr 2M Reihen, die zu ungefähr einer 100k Reihe sich verbinden. Also waren 10 Sekunden in Ordnung. – Bsbal18

0

Ich würde Sie von der Verwendung eines (komplexen) abraten JOIN mit OR-Zustand auf etwas größeren Tabellen (50k +), wie die Ausführung Plan kann völlig aus meiner eigenen Erfahrung verrückt werden.

Unter solchen Umständen eher eine Union verwenden (select cond1_match) union all (select cond2_default) bestellt/gewählt und wählen Sie die erste Zeile oder ein JOIN verwenden wie

select coalesce(a1.prin, a2.prin) 
from (select cond1_match) a1 
full join (select cond2_default) a2 

Und wenn Sie richtig verstehen, dass Sie nur eine Zahl als Eingabe und wollen beitreten eine weitere Datentabelle, dann mein Vorschlag wie dieses

with 
    tbl (SYSTEM, PRIN, DATA) as (
     select 80, 0, 2 from dual union all 
     select 80, 1, 3 from dual union all 
     select 80, 2, 4 from dual 
    ), 
    tbl2 (SYSTEM, PRIN, OTHERDATA) as (
     select 80, 0, 99 from dual union all 
     select 80, 1, 333 from dual union all 
     select 80, 2, 444 from dual 
    ) 
select t.system, t.prin, t.data, tt.otherdata 
from tbl t 
inner join tbl2 tt on t.system = tt.system and t.prin = tt.prin 
where t.prin = (select nvl(max(prin), 0) from tbl where system = t.system and prin = :pri) 
; 

System + prin einzigartig oder max() zufällig aussehen würde, hätte sein sein

: pri = 5

SYSTEM PRIN DATA OTHERDATA 
------ ---- ---- --------- 
80  0  2  99 

: pri = 2

SYSTEM PRIN DATA OTHERDATA 
------ ---- ---- --------- 
80  2  4  444 

Nur etwa tbl2 und die Join-Bedingung zu erraten, aber das ist im Grunde, wie mir gesagt wurde, Daten zu suchen oder einen Standard verwenden, wenn NO_DATA_FOUND in SQL