2016-11-07 4 views
-2

Ich möchte mehrere Tabellen abfragen, aber nur eindeutige Datensätze zurückgeben.Oracle: Wie unterschiedliche Datensätze aus mehreren Tabellen abfragen?

Meine aktuelle Abfrage:

select 
    a.*, 
    b.*, 
    c.* 
from c_inv a 
    inner join p_master b 
     on a.c_code = b.c_code 
      and a.p_code = b.p_code 
    left join c_proj c 
     on b.c_code = c.c_code 
      and b.p_code = c.p_code 
where a.c_code = 'AA' 
    and a.d_type = 'IN' 
    and a.s_type = substr('OI',0,2) 
    and a.g_flag = 'N'  
    and a.startdate <= trunc(sysdate)  
    and nvl(a.enddate, trunc(sysdate)) >= trunc(sysdate) 
order by a.p_code 

Datenabtastblock

p_master 
c_code p_code 
AA  Test01   
AA  Test02 
AA  Test03 

c_proj 
c_code p_code  proj startdate enddate 
AA  Test99  clound 01/10/2016 31/10/2016 
AA  Test99  clound 01/09/2016 30/09/2016 
AA  Test99  clound 01/08/2016 31/08/2016 

meine aktuellen Ergebnisse:

c_code p_code 
AA  Test01   
AA  Test02 
AA  Test03 
AA  Test99 
AA  Test99 
AA  Test99 

Zielerreichung:

c_code p_code  proj 
AA  Test01  null  
AA  Test02  null 
AA  Test03  null 
AA  Test99  clound 
+0

Es scheint, dass Sie fehlen 'c_inv' Daten – Aleksej

Antwort

1

nicht sicher, wie diese Ausgabe nützlich, aber um es zu bekommen, müssen Sie UNION, kein beitreten. (Hinweis - UNION hat auch einen DISTINCT Betrieb, so dass Sie es nicht separat hinzufügen müssen.)

select p_code, c_code, null as proj from p_master 
union 
select p_code, c_code,   proj from c_proj 

Die Ergebnisse kommen in der gewünschten Reihenfolge gezeigt, oder in einer anderen Reihenfolge; Verwenden Sie explizit ORDER BY ...., wenn Sie eine bestimmte Reihenfolge benötigen.

0

wenn es eine Eins-zu-Eins-Abbildung zwischen c_code + p_code gegen Projekt dann folgende Abfrage funktioniert:

select a.c_code,a.p_code,max(proj) 
from c_inv a 
inner join p_master b 
    on a.c_code = b.c_code 
    and a.p_code = b.p_code 
left join c_proj c 
    on b.c_code = c.c_code 
    and b.p_code = c.p_code 
where a.c_code = 'AA' 
    and a.d_type = 'IN' 
    and a.s_type = substr('OI',0,2) 
    and a.g_flag = 'N'  
    and a.startdate <= trunc(sysdate)  
    and nvl(a.enddate, trunc(sysdate)) >= trunc(sysdate) 
group by a.c_code,a.p_code  
order by a.p_code 
0

Sie wollen die Anzahl der Zeilen zu reduzieren. Das schlägt einen von zwei Ansätzen vor: entweder Aggregation oder Verwendung einer Fensterfunktion wie row_number(). Der Aggregationsansatz würde wie folgt aussehen:

Ich habe die Tabellenaliase geändert, um Abkürzungen für die Tabellennamen zu sein. Dies erleichtert das Folgen der Abfrage.

Auch in SQL, die Positionen in Strings beginnen bei "1" und nicht "0", so änderte ich den substr() Aufruf.

+0

' distinct' reduziert auch die Anzahl der Zeilen (und scheint mit der OP-Ausgabe übereinzustimmen). Und "distinct" wird durch mengentheoretische Operationen subsumiert (außer "union all" - was sowieso KEINE satztheoretische Operation ist). – mathguy

Verwandte Themen