Umlüx
Huge Metal Fan
|
folgendes problem, ich sitze momentan komplett auf der leitung.. Ich habe zwei tabellen in einer Oracle DB Tabelle 1
---------
1 Test1
2 Test2
3 Test3
4 Test4
Tabelle 2
---------
Test1 A
Test2 B
Test3 A
Test3 B
Test4 B
Test4 C
die beiden möchte ich nun so joinen, dass er mir immer den wert "A" ausgibt wenn dieser in Tabelle 2 vorkommt, und sonst die spalte leer oder null lässt. mein hauptproblem momentan dabei: im falle von "Test3" darf dann auch nur ein result mit "A" zurückkommen, bei "Test4" nur eine mit leer/null. ich hoffe ich habe das halbwegs verständlich ausgedrückt.. DANKE!
|
berndy2001
|
Quick und Dirty fällt mir ein Subquerie mit where spalte2 = 'A' ein
|
Umlüx
Huge Metal Fan
|
hatte ich schonmal, aber dann fehlen mir die spalte != A komplett. oder ich bin zu deppat...
|
meepmeep
Here to stay
|
so eventuell? select t1.name, t2.category from table1 t1 left outer join table2 t2 on (t2.name = t1.name AND t2.category = 'A');
Bearbeitet von meepmeep am 03.09.2019, 11:36
|
Umlüx
Huge Metal Fan
|
selbiges ergebnis. war mein erster gedanke (vom MySQL her, aber eventuell funktioniert Oracle hier anders?),aber die != A fehlen dann komplett. im prinzip solls am ende so aussehen: 1 Test1 A
2 Test2
3 Test3 A
4 Test4
|
meepmeep
Here to stay
|
das tut es bei mir. Es ist halt wichtig, dass es left outer join ist. Das sorgt dafür, dass das ergebnis auch die Inhalte der Linken Seite enthält, wenn das join kriterium nicht aufgeht. create table table1 (
name varchar2(50)
);
--drop table table1;
create table table2 (
name varchar2(50),
category varchar2(50)
);
--drop table table2;
insert into table1 values ('test1');
insert into table1 values ('test2');
insert into table1 values ('test3');
insert into table1 values ('test4');
insert into table2 values ('test1', 'A');
insert into table2 values ('test2', 'B');
insert into table2 values ('test3', 'A');
insert into table2 values ('test3', 'B');
insert into table2 values ('test4', 'B');
insert into table2 values ('test4', 'C');
select t1.name, t2.category from table1 t1 left outer join table2 t2 on (t2.name = t1.name AND t2.category = 'A');
output:
test2
test4
test3 A
test1 A
Bearbeitet von meepmeep am 03.09.2019, 11:50
|
Umlüx
Huge Metal Fan
|
interessant. ich bekomme 1 Test1 A
3 Test3 A
|
JDK
Oberwortwart
|
Wenn du als Ergebnis eh nur eine Spalte aus T2 haben willst, warum dann ein Join? SELECT CASE WHEN C2 = 'A' THEN C2 ELSE NULL END AS Result FROM T2;
Gibt dir eine Liste mit allen Einträgen der zweiten Spalte (C2) aus der zweiten Tabelle (T2), wobei alle Ergebnisse != 'A' genulled werden. Wenn C1 noch dazu soll: SELECT C1, CASE WHEN C2 = 'A' THEN C2 ELSE NULL END AS Result FROM T2;
Oder willst du die Einträge aus T1 doch haben? Dann sollte meepmeeps Query eh passen. Wenn es nicht das gewünschte Ergebnis liefert, kannst du ein RIGHT JOIN machen (du willst ja alle Einträge aus T2 haben) und alle T2.C2 != 'A' wieder mit dem CASE abändern.
Bearbeitet von JDK am 03.09.2019, 12:05
|
Umlüx
Huge Metal Fan
|
ja ich will die aus T1 auch haben. Mit meeps query bekomm ich aber nur noch die "A" einträge zurück, mit deinem dafür alle. Test3 und Test4 sind dann doppelt drin. einmal mit A und einmal Null.
|
meepmeep
Here to stay
|
Und du bist dir sicher, dass du einen left outer join machst? Kannst du deine query mal posten?
|
JDK
Oberwortwart
|
Ah okay, ich glaub jetzt versteh ich, was du willst.
meepmeeps Query sollte dann passen (vlt noch SELECT DISTINCT, falls du mehrere Einträge mit T2.C2 = A pro Test hast).
|
Umlüx
Huge Metal Fan
|
SELECT DISTINCT B.BOOKINGNUMBER, B.TRAVELSTARTDATE, BPB.BUSINESSPARTNERNUMBER, BN.DEFAULTDESCRIPTION
FROM BOOKING B
LEFT JOIN TOP_SPR_PROD.BUSINESSPARTNERBASE BPB ON B.PAYINGBP_ID = BPB.ID
LEFT JOIN BOOKINGSERVICE BS ON BS.BOOKING_ID = B.ID
LEFT OUTER JOIN TOP_SPR_PROD.BOOKINGNOTE BN ON BN.BOOKINGSERVICE_ID = BS.ID AND BN.DEFAULTDESCRIPTION LIKE '*BN%'
WHERE BPB.BUSINESSPARTNERNUMBER = '123'
AND BN.NOTETYPE_ID = '81'
ORDER BY B.BOOKINGNUMBER
knackpunkt ist BN.DEFAULTDESCRIPTION, das sind notizen zur buchung. und es kann mehrere notizen pro buchung geben. er solls ausschreiben, wenn es einen eintrag gibt der mit '*BN' beginnt (und die restlichen ignorieren). oder eben leer lassen, wenn kein solcher vorkommt.
|
meepmeep
Here to stay
|
ohne dem join auf BOOKINGNOTE (also die Zeile komplett weg) enthält das Ergebnis die erwarteten Inhalte aus BOOKING? '*BN%' matched auch sicher die gesuchten Inhalte aus BN.DEFAULTDESCRIPTION?
|
berndy2001
|
hatte ich schonmal, aber dann fehlen mir die spalte != A komplett. oder ich bin zu deppat... so hätt ich gmeint: with tab1 as (
select decode(rownum, 1, 1, 2, 2, 3, 3, 4, 4) as id,
decode(rownum, 1, 'Test1', 2, 'Test2', 3, 'Test3', 4, 'Test4') as wert
from dual
connect by level <= 4
),
tab2 as (
select decode(rownum, 1, 'Test1', 2, 'Test2', 3, 'Test3', 4, 'Test3', 5, 'Test4', 6, 'Test4') as wert,
decode(rownum, 1, 'A', 2, 'B', 3, 'A', 4, 'B', 5, 'B', 6, 'C') as result
from dual
connect by level <= 6)
select tab1.*, (select result from tab2 where tab2.wert = tab1.wert and tab2.result = 'A') from tab1;
oder select tab1.*, tab2.* from tab1 left join tab2 on (tab2.wert = tab1.wert and tab2.result = 'A')
Bearbeitet von berndy2001 am 03.09.2019, 13:23
|
Umlüx
Huge Metal Fan
|
lass ich das "AND BN.DEFAULTDESCRIPTION LIKE '*BN%'" einfach weg, erhalte ich alle daten, ja. halt teilweise doppelt und dreifach, da es wie gesagt zu jeder BOOKINGNUMBER mehrere unterschiedliche BOOKINGNOTES geben kann.
mit dem AND.. bekomme ich nur noch die "*BN%"
aktuell spiele ich mich gerade mit LISTAGG herum um. idee wäre die Notes einfach zu kombinieren und dann auf den suchstring zu prüfen.
|