2017-04-12 5 views
1

So habe ich diese zwei Tabellen auf Oracle:Oracle Doppel wählen Ausgabe

CLIENT

cl_id cl_name 
1  John 
2  Maria 

ZAHLUNGEN

pa_id pa_date  pa_status cl_id 
1  2017-01-01  1   1 
2  2017-01-01  1   2 
3  2017-02-01  1   1 
4  2017-02-01  1   2 
5  2017-03-01  0   1 
6  2017-03-01  1   2 

ich wählen statemant müssen, die mir die Client-ID, NAME gibt und der Status seiner letzten Zahlung. So ist das Endergebnis meiner wählen sollte:

cl_id cl_name pa_status 
1  John  0 
2  Maria 1 

Dies ist der Client auswählen, das funktioniert:

select cl_id, cl_name from CLIENT;

Dies ist der letzte Status der Zahlung wählen, das funktioniert:

select * from ( select pa_status from PAYMENT ORDER BY PA_DATE DESC) where rownum = 1;

Also jetzt muss ich sie zusammen arbeiten lassen. Ich habe versucht, zwei Wege, die nicht funktioniert hat:

select cl_id, cl_name, (select * from ( select pa_status from PAYMENT ORDER BY PA_DATE DESC) where rownum = 1 and PAYMENT.cl_id = CLIENT.CL_ID) as last_status from CLIENT;

Fehler: ungültige Kennung

und dieses:

select cl_id, cl_name, (select * from ( select pa_status from PAYMENT ORDER BY PA_DATE DESC) where rownum = 1) as last_status from CLIENT;

, die geben mir keine Fehler, sondern nur zeigt den gleichen letzten Status von John, der der letzte Datensatz ist:

cl_id cl_name last_status 
1  John  0 
2  Maria 0 

Kann mir jemand einen Tipp geben?

Dank

Antwort

1

Sie müssen Analysis-Funktion verwenden. Mit dieser Art von Funktionen können Sie Ihre Daten in einige Gruppen aufteilen und die Daten für jede Gruppe nach Ihren Wünschen ordnen.

In Ihrem Fall:

Select * from (
Select id, name, status, row_number() over (partition by  p.cl_id order by p.pa_date desc) as rw 
From client c join payments p on p.cl_id = c.cl_id) 
Inn where inn.rw = 1; 
+0

Das hat gut geklappt. Vielen Dank! – Sambarilove

+0

großartig. Dafür gibt es eine noch bessere Syntax - suchen Sie nach der FIRST-Analysefunktion. Viel Glück! – user2671057

0

Dies wird das maximale Datum für die Kunden und bekommt dann die höchste Zahlung ID mit diesem Datum.

with max_date as (
     select max(date) as max_date, cl_id from payments group by cl_id 
) 
select c.cl_id, c.cl_name, p.pa_sttus from client c 
join payments p 
on c.cl_id = p.cl_id 
where p.pa_id = (select max(p2.pa_id) from payments p2 
        join max_date md 
        on p2.cl_id = md.cl_id 
        where p.cl_id = p2.cl_id 
        and p2.pa_date = md.max_date 
       ) 
+0

Das gibt mir eine ungültige Kennung in der letzten Zeile: "md.pa_date" – Sambarilove

+0

Ich verwendete den falschen Spaltennamen. sollte jetzt funktionieren. – gorrilla10101

0

zuerst die maximal Datum nehmen von für jeden clientid.

Select cl_id, max(pa_date) as pa_date from PAYMENTS group by cl_id 

Jetzt nehmen Sie ur-Client-Tabelle und kommen Sie mit über subquery

select c.cl_id, c.cl_name, 
(select pa_status from PAYMENT t where t.pa_date=p.pa_date and t.cl_id=p.cl_id) 
from CLIENT c join (Select cl_id, max(pa_date) as pa_date from PAYMENTS group by cl_id) p on p.cl_id=c.cl_id 
0

Sie können Oracle verwenden KEEP LAST hier:

select cl_id, c.cl_name, last_payment.status 
from client 
join 
(
    select 
    cl_id, 
    max(pa_status) keep (dense_rank last order by pa_date) as status 
    from payments 
    group by cl_id 
) last_payment using (cl_id); 

(Wenn Sie möchten, Kunden ohne Zahlungen enthalten, ändern die Verbindung zu LEFT OUTER JOIN.)