SQL: Abfrage über mehrere Tabellen ohne Primärschlüssel=Fremdschlüssel

Produkte - (Computer, Datenbank, MySQL) Verkaufsberichte - (Computer, Datenbank, MySQL) Ausgabe - (Computer, Datenbank, MySQL)

4 Antworten

Man kann Tabellen genz normal mit where-Bedingungen ohne join-Syntax verknüpfen. Auch ist dazu weder Primär- noch Fremdschlüssel erforderlich. Die Daten müssen das von der Logik natürlich hergeben, das ist klar. Es können auch Datengruppen verwendet werden, um die Sätze eindeutig zu identifizieren. Der Fremdschlüssel dient eigentlich nur dazu, seitens der Datenbank unerwünschte Eintragungen zu verhindern.

Beispiel:

 select * from tabelle-1, tabelle-2
 where tabelle-1.mitgliedsnr = tabelle-2.mitgliedsnr
 and tabelle-1.datum = tabelle-2.datum  

Hier werden zwei Tabellen miteinander verknüpft, deren Sätze mit der mitgliedsnr und dem datum gleichzeitig übereinstimmen (die Namen der Felder müssen nicht übereinstimmen, hier nur wegen der Übersichtlichkeit) . Ein Index sollte auf den Feldern schon vorhanden sein, zumindest bei größeren Datenmengen.

Ich betreibe seit 20 Jahren eine Datenbank für einen Rassehundeverein mit mittlerweile 55 Tabellen. Da sind auch Datenkonstruktionen dabei, die sich nicht mit dem klassischen Datenbankdesign lösen lassen, wie es in der Schule gelehrt wird. Bei einer Ahnentafel z.B. sind Eltern und Großeltern in der selben Tabelle gespeichert und müssen verknüpft werden. Eine SQL-Datenbank bietet weit mehr Anwendungsmöglichkeiten, als in der Schule gelehrt wird.

Ich mache übrigens alle Verknüpfungen auf diese Weise Das ist für mich übersichtlicher. Der Zugriff auf die Datenbank erfolgt meistens vom Programm aus über Embedded-SQL. Da gibt es oft einfachere Möglichkeiten zur Lösung von komplexen Zusammenhängen.

Hello there,

also was du da ausgegeben hast, nennt man kartesisches Produkt und was du durchgeführt hast, war wie richtig bemerkt wurde, ein CROSS JOIN. Aber aufgepasst! Unter MySQL gibt es den Befehl CROSS JOIN zwar, er führt aber keinen klassischen CROSS JOIN durch sondern bereinigt bereits, ähnlich einem INNER JOIN.

In der Regel wird dieses kartesische Produkt nicht gewünscht und muss daher bereinigt werden. Wie auch richtig erwähnt wurde, ist das Schlüsselwort JOIN nicht zwingend erforderlich.

Es gibt nämlich zwei gültige Syntax für die Formulierung eines Joins.

Das eine wäre explizit, weil du das Schlüsselwort JOIN "explizit" erwähnst.

Also so:

SELECT produktname,
       menge
FROM   verkaufsberichte
       CROSS JOIN produkte
WHERE  menge > 1000
ORDER  BY menge DESC;  

Unter MySQL ist dies äquivalent zu

SELECT produktname,
           menge
    FROM   verkaufsberichte
           INNER JOIN produkte
    WHERE  menge > 1000
    ORDER  BY menge DESC;  

Was du machst ist der implizite JOIN:

SELECT produktname,
       menge
FROM   verkaufsberichte,
       produkte
WHERE  menge > 1000
ORDER  BY menge DESC;

und den müsstest du natürlich noch bereinigen jetzt, genau - damit dein kartesisches Produkt weg ist:

SELECT produktname,
       menge
FROM   verkaufsberichte,
       produkte
WHERE  menge > 1000
    AND verkaufsberichte.produkte_produktnummer = produkte.produktnummer
ORDER  BY menge DESC;

Grundsätzlich ist der implizite JOIN ausreichend wenn du immer INNER JOINS machen musst, wenn du aber OUTER JOINS brauchst, dann wirds mit der impliziten Variante etwas unübersichtlich. Ich persönlich schreibe eigentlich nur explizite JOINS.

Hoffe nun bist du geholfen :) Vielleicht isses dir ja nen Stern wert

MfG

Alex

Was du da bekommst dürfte ein Cross-Join sein. Jede Zeile von Tabelle1 wird mit jeder Zeile von Tabelle2 Kombiniert.

SELECT p.Produktname, v.Menge FROM Produkte p LEFT JOIN Verkaufsberichte v ON (p.Produktnummer = v.Produkte_Produktnummer) WHERE v.Menge > 1000 ORDER BY v.Menge DESC;

Cross join inner join cross joint inner joint