SQL Join Problem

Seite 1 von 2 - Forum: Coding Stuff auf overclockers.at

URL: https://www.overclockers.at/coding-stuff/sql-join-problem_254298/page_1 - zur Vollversion wechseln!


Umlüx schrieb am 03.09.2019 um 11:20

folgendes problem, ich sitze momentan komplett auf der leitung..

Ich habe zwei tabellen in einer Oracle DB

Code:
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.. :D

DANKE!


berndy2001 schrieb am 03.09.2019 um 11:30

Quick und Dirty fällt mir ein Subquerie mit where spalte2 = 'A' ein


Umlüx schrieb am 03.09.2019 um 11:30

hatte ich schonmal, aber dann fehlen mir die spalte != A komplett.
oder ich bin zu deppat...


meepmeep schrieb am 03.09.2019 um 11:32

so eventuell?

Code: SQL
select t1.name, t2.category from table1 t1 left outer join table2 t2 on (t2.name = t1.name AND t2.category = 'A');


Umlüx schrieb am 03.09.2019 um 11:45

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:

Code:
1   Test1   A   
2   Test2
3   Test3   A
4   Test4


meepmeep schrieb am 03.09.2019 um 11:46

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.

Code: SQL
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');
Code:
output:
test2	
test4	
test3	A
test1	A


Umlüx schrieb am 03.09.2019 um 11:50

interessant. ich bekomme

Code:
1   Test1   A   
3   Test3   A


JDK schrieb am 03.09.2019 um 12:00

Wenn du als Ergebnis eh nur eine Spalte aus T2 haben willst, warum dann ein Join?

Code: SQL
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:
Code: SQL
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.


Umlüx schrieb am 03.09.2019 um 12:07

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 schrieb am 03.09.2019 um 12:09

Und du bist dir sicher, dass du einen left outer join machst?
Kannst du deine query mal posten?


JDK schrieb am 03.09.2019 um 12:18

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 schrieb am 03.09.2019 um 12:22

Code: SQL
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 schrieb am 03.09.2019 um 13:03

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 schrieb am 03.09.2019 um 13:15

Zitat aus einem Post von Umlüx
hatte ich schonmal, aber dann fehlen mir die spalte != A komplett.
oder ich bin zu deppat...

so hätt ich gmeint:
Code: SQL
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
Code: SQL
select tab1.*, tab2.* from tab1 left join tab2 on (tab2.wert = tab1.wert and tab2.result = 'A')

2019-09-03-13_14_51-oracle-sql-developer_239856.png


Umlüx schrieb am 03.09.2019 um 13:20

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.




overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025