Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [SQL] Outer Join (https://www.delphipraxis.net/145216-%5Bsql%5D-outer-join.html)

Synollus 26. Dez 2009 16:44


[SQL] Outer Join
 
Hi,

ich habe Folgendes vor: Ich möchte alle Zeilen in Tabelle A selektieren, deren ID nicht in Tabelle B vorkommen, ein "Verbinden" der Tabellen ist nicht nötig

Dennoch dachte ich mir, dass FULL OUTER JOIN dafür wie geschaffen wäre, aber nachdem ich diesen Artikel gelesen habe, bin ich total verwirrt (vielleicht habe ich es auch nur falsch verstanden).

Was bleibt mir denn jetzt noch übrig? :?

mkinzler 26. Dez 2009 16:54

Re: [SQL] Outer Join
 
In einem Outer join sind alle vorhanden ( left, right, full)
Nur die ohne bekommst du besser über einen Subselect

alzaimar 26. Dez 2009 18:40

Re: [SQL] Outer Join
 
SQL-Code:
select a.* 
  from tabelle1 a left join
       tabelle2 b on a.PK = b.FK
 where b.FK is null
liefert alle Datensätze aus Tabelle1, deren PK nicht in der Spalte 'FK' der Tabelle2 enthalten ist.

Synollus 27. Dez 2009 09:13

Re: [SQL] Outer Join
 
Danke euch beiden. Auf die Idee mit dem Subselect bin ich nicht gekommen. :wall:

Welche von beiden Varianten ist jetzt die effizientere oder nehmen sie sich nicht viel?

mkinzler 27. Dez 2009 09:15

Re: [SQL] Outer Join
 
Das kommt auf das DBMS an.

Synollus 27. Dez 2009 16:17

Re: [SQL] Outer Join
 
Das DBMS dürfte MySQL sein, wenn ich die Begriffe nicht verwechsel, oder meinst du die Engine à la InnoDB oder MyISAM?

Niko 27. Dez 2009 16:29

Re: [SQL] Outer Join
 
Ohne die Interna von MySQL zu kennen, sollte es keinen großen Unterschied geben, da der Optimierer die Subquery wohl zunächst in einen Join auflösen wird. Sonst hilft nur ausprobieren, wobei du das immer noch machen kannst, wenn sich herausstellt, dass dein Programm zu langsam ist.

omata 27. Dez 2009 18:39

Re: [SQL] Outer Join
 
So und jetzt nochmal, wie man das normalerweise lösen würde...
SQL-Code:
SELECT *
FROM tabelle1 a
WHERE NOT EXISTS (SELECT *
                  FROM tabelle2 
                  WHERE FK = a.PK)

alzaimar 27. Dez 2009 21:37

Re: [SQL] Outer Join
 
Zitat:

Zitat von omata
So und jetzt nochmal, wie man das normalerweise lösen würde...

Äh... nö? Die Lösung mit einem LEFT JOIN ist doch mindestens gleichwertig (siehe u.a. "Inside SQL-Server xxxxx", Soukup und Delaney).

omata 27. Dez 2009 23:34

Re: [SQL] Outer Join
 
Das mag ja sein, es ist aber trotzdem ein Hack und somit nur gefrickel. Ich setzt es auch manchmal ein, aber es geht nunmal nichts über kommulierte Unterabfragen (in diesem benötigten Bereich).

1carter1 28. Dez 2009 11:04

Re: [SQL] Outer Join
 
solche subquerys die du da benutzt sollte man immer versuchen zu vermeiden, dadurch wird der code einfach nur unnötig lang und u.u. auch unverständlich.

joins sind viel besser für solche sachen und btw sind sie kein hack, wo hast'n du den schmarn her?
Und es ist auch kein gefrickel wenn man weiß wie man die dinger benutzt ;)

omata 28. Dez 2009 12:02

Re: [SQL] Outer Join
 
Das ist absoluter Blödsinn.

Ich habe nichts gegen Joins, aber erstmal sind lange Abfragen völlig ok. Zweitens ist der EXISTS-Operator sehr effizient und drittens führen viele Wege nach Rom.

Wenn die Tabelle2 für einen Datensatz in Tabelle1 mehrere Zeilen enthält, vergrößert sich das Ergebnis. Da ist die EXISTS-Methode wesentlich sinnvoller. Vermutlich würdet ihr in dem Fall dann noch ein SELECT DISTINCT verwendet, autsch!

Also ne ne, ich weiß nicht, eure eingeschränkte Sicht der Dinge ist schon ziemlich traurig.

PS: Mein Beispiel passt nicht 100% zum Ursprung, trotzdem ist ein OUTER JOIN hier genauso möglich wie der EXISTS-Operator. Für mich persönlich ist dann der EXISTS-Operator sinnvoller und übersichtlicher. Aber ich bin ja nur ein unwissender Idiot und Ihr die Helden dieser Welt. Also weiter frickeln...

Niko 28. Dez 2009 13:59

Re: [SQL] Outer Join
 
Dass der EXISTS-Operator an sich sehr effizient implementiert werden kann, ist sicher korrekt. Die Variante von omata hat aber den Nachteil, dass die Subquery abhängig ist von der äußeren Query, weshalb sie für jedes Ergebnistupel der äußeren Query einmal ausgeführt werden muss. Das ist der Grund, warum es sich normalerweise empfiehlt, abhängige Subqueries zu vermeiden.


Eine andere Subquery-Variante wäre übrigens die folgende:
SQL-Code:
select * 
  from tabelle1
  where PK not in (select FK from tabelle2)
Diese dürfte von der Performance her dem Vorschlag von alzaimar entsprechen, weil DB-Intern ein Join draus wird. Wenn über PK und FK je ein Index existiert, kann dieser sehr effizient ausgeführt werden.

Ich persönlich finde die Subquery-Variante etwas übersichtlicher, aber das ist Geschmack- und Gewohnheitssache.

omata 28. Dez 2009 17:31

Re: [SQL] Outer Join
 
Das mag alles sein, trotzdem habe ich schon öfters eine Geschwindigkeitssteigerung erreicht, durch den Einsatz des EXISTS-Operators. Der verwendete JOIN war einfach langsamer. Und das brachte bei MySQL, MSSQL und auch Firebird merkliche Verbesserungen. Ok, dass waren SQL-Statements, die eine DIN A4 Seite füllen, aber wie gesagt, der EXISTS-Operator sollte nicht vernachlässigt werden, er ist nunmal sehr effizient und auch sehr schnell.
Aber wie auch immer, macht doch was ihr wollt. Ignoriert bitte einfach, was ich schreibe...


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz