Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

LEFT JOIN auflösen

40 views
Skip to first unread message

Marco Klemm

unread,
Dec 6, 1998, 3:00:00 AM12/6/98
to
Hallo SQL-Spezialisten,

kann mir jemand sagen, wie man einen LEFT JOIN
auflöst? Also z.B. so etwas:

SELECT *
FROM HauptTab h LEFT JOIN DetailTab d ON (h.id = d.id)

Wie müßte die entsprechende ANSI-SQL-Anweisung aussehen?
Die Anweisung

SELECT *
FROM HauptTab h, DetailTab d
WHERE h.id = d.id

reicht ja wohl nicht.

Danke...

Cu, Marco

Volker Fraenkle

unread,
Dec 8, 1998, 3:00:00 AM12/8/98
to
Hallo Marko,

wie wäre es mit

select ... from
HauptTab h OUTER DetailTab d
where ...

Gruß Volker

Marco Klemm schrieb:

--
Volker Fraenkle CS Controlling
Technical Consultant Software Systeme GmbH

E-Mail: VFra...@cs-controlling.de
Phone: +49 7144 8144-0 Riedbachstrasse 5
Fax: +49 7144 8144-10 D-74385 Pleidelsheim

Marco Klemm

unread,
Dec 8, 1998, 3:00:00 AM12/8/98
to
Hallo Volcer (*ich* werde mit "c" geschrieben ;-)

Volker Fraenkle schrieb:


>
> Hallo Marko,
>
> wie wäre es mit
>
> select ... from
> HauptTab h OUTER DetailTab d
> where ...

Ist "Outer" ANSI-SQL?

Es muß doch irgendwie möglich sein,
einen Left-Join in der WHERE-Klausel zu deklarieren.

Hintergrund ist, daß ich gerne verstehen möchte, was
das Datenbanksystem macht, wenn ich einen JOIN ... ON anwende.

Ich hab irgendwie so etwas im Kopf, (ist aber falsch):

SELECT ...

FROM HauptTab h, DetailTab d

WHERE h.id = d.id // Join-Bedingung
OR d.id IsNull // Left-Join-Bedingung?

<grins>

Ich habe so die Befürchtung, daß die LEFT oder RIGHT
OUTER JOIN's ziemlich performance-kritisch sind.

Wahrscheinlich müßte man deshalb obigen Versuch (einen LEFT JOIN
zu simulieren) mit einer Unterabfrage erweitern, oder?

Cu, Marco

Dieter Nöth

unread,
Dec 8, 1998, 3:00:00 AM12/8/98
to
Hi Marco,

Marco Klemm wrote in message <366B021C...@gmx.de>...


>Hallo SQL-Spezialisten,
>
> kann mir jemand sagen, wie man einen LEFT JOIN
>auflöst? Also z.B. so etwas:
>
>SELECT *
>FROM HauptTab h LEFT JOIN DetailTab d ON (h.id = d.id)
>
>Wie müßte die entsprechende ANSI-SQL-Anweisung aussehen?

das ist schon ANSI genug

ganz offiziell wäre es:
SELECT *
FROM HAUPTTAB AS H LEFT OUTER JOIN DETAILTAB AS D
ON (H.ID = D.ID)

(in ANSI gibt's nur großgeschriebene Bezeichner, wie DBase...)

>Die Anweisung
>
>SELECT *


>FROM HauptTab h, DetailTab d
>WHERE h.id = d.id

>
>reicht ja wohl nicht.

Nee, das ist nur nicht-ANSI für INNER JOIN

Die Performance für einen Outer Join ist natürlich langsamer
als für einen einfachen Inner Join (das hängt auch stark von
der Datenbank ab), aber immer noch besser als das
Äquivalent OHNE Outer Join -- eine UNION des Inner Joins
mit allen Records, die nicht gejoint werden können:

SELECT *
FROM HauptTab h INNER JOIN DetailTab d
ON (h.id = d.id)

UNION

SELECT AlleSpaltenVonTabH, NULLsFürAlleSpaltenVonTabd
FROM HauptTab h
WHERE h.id IS NULL
OR h.id NOT IN (SELECT id from DetailTab)

Tschüß
Dieter

Martin Zahl

unread,
Dec 8, 1998, 3:00:00 AM12/8/98
to
Hallo,

> kann mir jemand sagen, wie man einen LEFT JOIN
>auflöst? Also z.B. so etwas:
>
>SELECT *
>FROM HauptTab h LEFT JOIN DetailTab d ON (h.id = d.id)
>
>Wie müßte die entsprechende ANSI-SQL-Anweisung aussehen?

>Die Anweisung
>
>SELECT *
>FROM HauptTab h, DetailTab d
>WHERE h.id = d.id


Also bei mir klappt:


SELECT *
FROM HauptTab h, DetailTab d

WHERE h.ID*=d.id;

Ich weiß jedoch nicht genau, ob das ANSI-Standard ist.
Ich denke eher, das es ein "Feature" des Sybase SQL-Servers ist, den ich
benutze.

---
Bye,
Martin

// Lieber 6 Stunden Uni, als gar kein Schlaf !!
// PGP-Key avail. by eMail "Subject: send pgp-key"


Thomas Sommerfeld

unread,
Dec 9, 1998, 3:00:00 AM12/9/98
to
In Artikel <366B021C...@gmx.de> sagt DonL...@gmx.de ...
> Hallo SQL-Spezialisten,

>
> kann mir jemand sagen, wie man einen LEFT JOIN
> auflöst? Also z.B. so etwas:
>
> SELECT *
> FROM HauptTab h LEFT JOIN DetailTab d ON (h.id = d.id)
>
> Wie müßte die entsprechende ANSI-SQL-Anweisung aussehen?
> Die Anweisung
>
> SELECT *
> FROM HauptTab h, DetailTab d
> WHERE h.id = d.id
>
> reicht ja wohl nicht.
>
> Danke...
>
> Cu, Marco
>
Die Anweisung mit LEFT JOIN ist die ANSI-SQL-Anweisung, diese Art von
Joins ist allerdings erst ab Intermediate SQL definiert, nicht in Entry
SQL. Leider verstehen aber die wenigsten Datenbanken wirklichen SQL/92-
konforme Anweisungen; speziell bei den Joins hat wohl jeder DB-Hersteller
so seine eigene Lösung. Bei Oracle z.B. erfolgt die Abfrage mit folgender
Syntax:
SELECT *
FROM HauptTab H, DetailTab D
WHERE H.ID = D.ID (+)

Es bleibt da leider nichts anders übrig, als für jede unterstützte DB
eine eigene Abfrage zu erstellen (außer man unterstützt natürlich mehrere
DB mit der gleichen Syntax).

Bis dann
Thomas

Marco Klemm

unread,
Dec 9, 1998, 3:00:00 AM12/9/98
to
Hallo Dieter,

Dieter Nöth schrieb:


>
> Marco Klemm wrote in message <366B021C...@gmx.de>...
> >

> > kann mir jemand sagen, wie man einen LEFT JOIN
> >auflöst? Also z.B. so etwas:
> >
> >SELECT *
> >FROM HauptTab h LEFT JOIN DetailTab d ON (h.id = d.id)
> >
> >Wie müßte die entsprechende ANSI-SQL-Anweisung aussehen?
>

> das ist schon ANSI genug

Also versteh ich das richtig, daß obige SELECT-Anweisung
von allen gängigen Datenbanksystemen verstanden wird?
Besonders wichtig ist für mich Oracle (habe leider
kein Oracle auf meinem PC installiert, mit dem ich das
testen könnte.)

> Die Performance für einen Outer Join ist natürlich langsamer
> als für einen einfachen Inner Join (das hängt auch stark von
> der Datenbank ab), aber immer noch besser als das
> Äquivalent OHNE Outer Join

Wieso ist die Performance denn unterschiedlich?
Du schreibst doch von dem "Äquivalent", also gleich ;o)

Aber mal ernst, gibt es da Performance-Unterschiede, wenn
ich die JOIN's manuell erzeuge im Unterschied
zu "JOIN ... ON ..."?
Konkret: Behandelt der Optimierer beide Anweisungen unter-
schiedlich? Dürfte theoretisch ja nicht der Fall sein.
(Aber was ist in der Praxis schon theoretisch.)

> -- eine UNION des Inner Joins
> mit allen Records, die nicht gejoint werden können:
>

> SELECT *
> FROM HauptTab h INNER JOIN DetailTab d
> ON (h.id = d.id)
>

> UNION
>
> SELECT AlleSpaltenVonTabH, NULLsFürAlleSpaltenVonTabd
> FROM HauptTab h
> WHERE h.id IS NULL
> OR h.id NOT IN (SELECT id from DetailTab)

Ach her je, genau so etwas habe ich befürchtet ;-)
Aber das beantwortet zumindest meine Ausgangsfrage.

Jetzt habe ich noch eine Frage zu UNION:
Müssen beide SELECT-Anweisungen die gleichen Spalten
in der gleichen Reihenfolge zurückliefern?

Cu, Marco

Marco Klemm

unread,
Dec 9, 1998, 3:00:00 AM12/9/98
to
Thomas Sommerfeld schrieb:

>
> Die Anweisung mit LEFT JOIN ist die ANSI-SQL-Anweisung, diese Art von
> Joins ist allerdings erst ab Intermediate SQL definiert, nicht in Entry
> SQL.

Interdmediate und Entry? Sind das verschiedene Versionen?

> Leider verstehen aber die wenigsten Datenbanken wirklichen SQL/92-
> konforme Anweisungen; speziell bei den Joins hat wohl jeder DB-Hersteller
> so seine eigene Lösung. Bei Oracle z.B. erfolgt die Abfrage mit folgender
> Syntax:
> SELECT *
> FROM HauptTab H, DetailTab D
> WHERE H.ID = D.ID (+)

Das ist ja eine Frechheit. Was hat sich Oracle bloß dabei gedacht? ;-)



> Es bleibt da leider nichts anders übrig, als für jede unterstützte DB
> eine eigene Abfrage zu erstellen (außer man unterstützt natürlich mehrere
> DB mit der gleichen Syntax).

Soviel zu dem Standard-SQL...

Es wird wohl noch einige Zeit dauern, bis man einfach durch
Ändern des Alias zwischen Datenbanksystemen "umswitschen" kann.

Cu, Marco

Oliver Stoer

unread,
Dec 9, 1998, 3:00:00 AM12/9/98
to
On Wed, 09 Dec 1998 10:27:42 +0000, Marco Klemm <DonL...@gmx.de> wrote:

>> Die Anweisung mit LEFT JOIN ist die ANSI-SQL-Anweisung, diese Art von
>> Joins ist allerdings erst ab Intermediate SQL definiert, nicht in Entry
>> SQL.
>
>Interdmediate und Entry? Sind das verschiedene Versionen?

Nicht ganz. Es gibt drei verschieden sog. Conformance-Level. Entry,
Intermediate und Full. Der Entry-Level wird von allen RDBMS unterstützt. Er
entspricht im wesentlichen dem SQL89-Standard. Wenn Du Applikationen
schreibst, die mit verschiedenen RDBMS laufen sollen, kannst Du praktisch
nur SQl89 verwenden. Er ist der kleinste gemeinsame Nenner aller RDBMS. Die
meisten Datenbanken unterstützen aber auch Teile der anderen Levels. Welche
bleibt dabei ihnen selbst überlassen (Immerhin gibt es im Entry-Level 178
funktionale Einschränkungen gegenüber dem Full-Standard). Der Full-Level
wird von keinem RDBMS unterstützt.
Die Einteilung in verschiedene Level rührt daher, daß es relationale DBMS
schon lange vor SQL gab. Verschiedene Hersteller haben verschieden Teile von
Codd's ursprünglichem "Relationalen Modell" implementiert. Irgendwann war
dann das Bedürfnis danach die zahllosen proprietären Abfragesprachen zu
Vereinheitlichen. Warum ausgerechnet SQL das Rennen gewonnen hat, wissen die
Götter. Wahrscheinlich, weil es von IBM kam.

[...]



>> Es bleibt da leider nichts anders übrig, als für jede unterstützte DB
>> eine eigene Abfrage zu erstellen (außer man unterstützt natürlich mehrere
>> DB mit der gleichen Syntax).

Ich denke wenn Du den SQL92-Entry-Level oder SQL89-Syntax benutzt sollten
die Abfragen auf allen Datenbanken laufen.

>Soviel zu dem Standard-SQL...

SQL hat dasselbe Desaster wie bei HTML schon viel länger mitgemacht. ;-)

>Es wird wohl noch einige Zeit dauern, bis man einfach durch
>Ändern des Alias zwischen Datenbanksystemen "umswitschen" kann.

Wahrscheinlich noch 20 bis 50 Jahre. ;-)

Oliver
--
50°00'00" N
08°36'32" E

Marco Klemm

unread,
Dec 9, 1998, 3:00:00 AM12/9/98
to
Oliver Stoer schrieb:

>
> On Wed, 09 Dec 1998 10:27:42 +0000, Marco Klemm <DonL...@gmx.de> wrote:
>
> >> Die Anweisung mit LEFT JOIN ist die ANSI-SQL-Anweisung, diese Art von
> >> Joins ist allerdings erst ab Intermediate SQL definiert, nicht in Entry
> >> SQL.
> >
> >Interdmediate und Entry? Sind das verschiedene Versionen?
>
> Nicht ganz. Es gibt drei verschieden sog. Conformance-Level. Entry,
> Intermediate und Full. Der Entry-Level wird von allen RDBMS unterstützt. Er
> entspricht im wesentlichen dem SQL89-Standard. Wenn Du Applikationen
> schreibst, die mit verschiedenen RDBMS laufen sollen, kannst Du praktisch
> nur SQl89 verwenden. Er ist der kleinste gemeinsame Nenner aller RDBMS. Die
> meisten Datenbanken unterstützen aber auch Teile der anderen Levels. Welche
> bleibt dabei ihnen selbst überlassen (Immerhin gibt es im Entry-Level 178
> Der Full-Level wird von keinem RDBMS unterstützt.

Warum entwickeln die DB-Hersteller den nicht mal fertig, bevor sie an
SQL 3 denken? Aber ich finde das schon irgendwie witzig :-)

> Ich denke wenn Du den SQL92-Entry-Level oder SQL89-Syntax benutzt sollten
> die Abfragen auf allen Datenbanken laufen.

Wo wir wieder beim Thema wären.
Wie krieg ich einen Left Outer Join hin, der für Paradox und Oracle läuft?
Nach den anderen Postings zu urteilen, geht es wohl nicht.
Aber ich finde Fallunterscheidungen so lästig.

Wie macht man denn einen Left Outer Join in Entry? Bzw. unterstützt
jede DB mit Intermediate SQL auch Entry SQL?

> Wahrscheinlich noch 20 bis 50 Jahre. ;-)

Dann könnte ich schon Rentner sein, und es wird mir in der Toscana
wohl egal sein ;-)

Cu, Marco

Heinz Z.

unread,
Dec 10, 1998, 3:00:00 AM12/10/98
to
Hallo Marco,

lese alle SQL-Anweisungen aus eine Datei, Ini-Datei oder der Registry
(Vorher mußt du sie natürlich auch darein schreiben :-)) oder hole dir die
SQL-Anweisungen aus einer DLL,
die du für jeden Unterstützten Server bereitstellst.

Das ist Arbeit??? Klar, laß es dir gut bezahlen :-))

Ciao Heinz

Thomas Sommerfeld

unread,
Dec 10, 1998, 3:00:00 AM12/10/98
to
In Artikel <366F0C7C...@gmx.de> sagt DonL...@gmx.de ...

> Warum entwickeln die DB-Hersteller den nicht mal fertig, bevor sie an
> SQL 3 denken? Aber ich finde das schon irgendwie witzig :-)

Ist ja schön, daß Du das noch witzig findest ;-) Wart' mal ab, bis Du
Applikationen schreibst, die fünf oder zehn verschiedene RDBMSe
unterstützen sollen. Warum imlementieren die DB-Hersteller den Standard
nicht vollständig? Weil es eben schwierig wird, ein Produkt wirklich bis
in's letzte Detail fertig zu entwicklen und es einfacher ist, neue tolle
Funktionen einzubauen, mit denen man andere blenden kann. Nenn mal ein
Betriebssystem, ein Entwicklungswerkzeug, eine Textverarbeitung, ...
das/die wirklich bis in's letzte funktioniert???

> > Ich denke wenn Du den SQL92-Entry-Level oder SQL89-Syntax benutzt sollten
> > die Abfragen auf allen Datenbanken laufen.
>
> Wo wir wieder beim Thema wären.
> Wie krieg ich einen Left Outer Join hin, der für Paradox und Oracle läuft?
> Nach den anderen Postings zu urteilen, geht es wohl nicht.

Richtig, es geht nicht. Es gibt in Entry-SQL keine Möglichkeit, einen
Outer Join zu simulieren. Prinzipiell müßte es ungefähr so aussehen:
SELECT H.*, D.*


FROM HauptTab H, DetailTab D
WHERE H.ID = D.ID

UNION ALL
SELECT H.*, NULL, NULL, NULL, ... NULL
FROM HauptTab H
WHERE NOT EXISTS
(SELECT *
FROM DetailTab D
WHERE H.ID = D.ID)
Nach Entry-SQL ist NULL aber kein gültiges Select-Element :-((

> Aber ich finde Fallunterscheidungen so lästig.

Sei froh, daß die DB-Hersteller wenigstens so intelligent waren, eigene
Lösungen dafür zu imlementieren, sonst gäbe es echte Probleme. ;-(

> Wie macht man denn einen Left Outer Join in Entry? Bzw. unterstützt
> jede DB mit Intermediate SQL auch Entry SQL?

Ja, Entry SQL ist gemäß Definition eine echte Teilmenge von Intermediate
SQL, was wiederum eine echte Teilmenge von Full SQL darstellt.

> > Wahrscheinlich noch 20 bis 50 Jahre. ;-)>

Schön, daß Du so optmistisch bist, anzunehmen, daß das überhaupt mal
funktionieren wird ;-)

> Dann könnte ich schon Rentner sein, und es wird mir in der Toscana
> wohl egal sein ;-)

Da freu' ich mich auch schon drauf.

Bis dann
Thomas

Marco Klemm

unread,
Dec 10, 1998, 3:00:00 AM12/10/98
to
Hallo Heinz,

Heinz Z. schrieb:

LOL, ich werde es einbringen :-)))

Marco Klemm

unread,
Dec 10, 1998, 3:00:00 AM12/10/98
to
Thomas Sommerfeld schrieb:

>
> In Artikel <366F0C7C...@gmx.de> sagt DonL...@gmx.de ...
>
> Ist ja schön, daß Du das noch witzig findest ;-)

:-)

> Nenn mal ein
> Betriebssystem, ein Entwicklungswerkzeug, eine Textverarbeitung, ...
> das/die wirklich bis in's letzte funktioniert???

Da schreit aber auch keiner nach "Standard", jedenfalls jetzt noch nicht.

Prinzipiell müßte es ungefähr so aussehen:
> SELECT H.*, D.*
> FROM HauptTab H, DetailTab D
> WHERE H.ID = D.ID
> UNION ALL
> SELECT H.*, NULL, NULL, NULL, ... NULL
> FROM HauptTab H
> WHERE NOT EXISTS
> (SELECT *
> FROM DetailTab D
> WHERE H.ID = D.ID)
> Nach Entry-SQL ist NULL aber kein gültiges Select-Element :-((

Das könnte meine Performance-Probleme erklären.


Vielen Dank euch allen, war wirklich sehr lehrreich.

Cu, Marco

0 new messages