Frage

Der Einfachheit halber nehmen alle relevanten Felder sind NOT NULL.

Sie können tun:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

Oder:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

Haben diese beiden Arbeiten auf die gleiche Weise in MySQL?

War es hilfreich?

Lösung

INNER JOIN ist ANSI-Syntax, die Sie verwenden sollen.

Es ist allgemein besser lesbar betrachtet, vor allem wenn Sie viele Tabellen verbinden.

Es kann auch leicht mit einem OUTER JOIN ersetzt werden, wenn ein Bedarf besteht.

Die WHERE Syntax mehr relationales Modell orientiert ist.

Ein Ergebnis von zwei Tabellen JOINed ist ein kartesisches Produkt der Tabellen, auf denen ein Filter angewandt wird, die nur die Zeilen mit Verbindungssäulen passend auswählt.

Es ist einfacher zu sehen, das mit der WHERE Syntax.

Wie bei Ihrem Beispiel in MySQL (und in SQL im Allgemeinen) diese beiden Abfragen sind Synonyme.

Beachten Sie auch, dass MySQL auch eine STRAIGHT_JOIN Klausel hat.

Mit dieser Klausel verwenden, können Sie die JOIN Reihenfolge steuern. Die Tabelle in der äußeren Schleife abgetastet wird, und welches ist in der inneren Schleife

Sie können dies nicht in MySQL steuern WHERE Syntax.

Andere Tipps

Andere haben darauf hingewiesen, dass INNER JOIN hilft menschliche Lesbarkeit, und das ist eine oberste Priorität; Genau. Lassen Sie uns versuchen zu erklären, warum die Join-Syntax ist besser lesbar.

Eine grundlegende SELECT-Abfrage ist dies:

SELECT stuff
FROM tables
WHERE conditions

Die SELECT-Klausel sagt uns was wir sind immer wieder; der FROM-Klausel sagt uns, Dabei gilt: wir bekommen es aus, und die WHERE-Klausel sagt uns die , die wir sind immer.

JOIN ist eine Aussage über die Tabellen, wie sie zusammen gebunden sind (vom Konzept her eigentlich in eine einzige Tabelle). Jede Abfrage Elemente, um die Tabellen zu steuern - wo bekommen wir Sachen aus - semantisch zu dem gehören FROM-Klausel (und natürlich, das ist, wo JOIN Elemente gehen). die Indienststellung Verbindungselemente in WHERE-Klausel verschmilzt die die und wo-von ; das ist, warum die JOIN-Syntax bevorzugt wird.

Anwenden von bedingten Anweisungen in ON / WHERE

Hier habe ich über die logische Abfrage Verarbeitungsschritte erläutert.


Referenz: Inside Microsoft® SQL Server ™ 2005 T-SQL-Abfragen
Verlag: Microsoft Press
Pub Datum: 7. März 2006
Drucken ISBN-10: 0-7356-2313-9
Drucken ISBN-13: 978-0-7356-2313-2
Seiten: 640

Innerhalb Microsoft® SQL Server ™ 2005 T -SQL Querying

(8)  SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>

Der erste spürbare Aspekt von SQL, die anders als anderen Programmiersprachen ist, ist die Reihenfolge, in der der Code verarbeitet wird. In den meisten Programmiersprachen wird der Code in der Reihenfolge bearbeitet, in der es geschrieben ist. In SQL, die die erste Klausel verarbeitet wird, ist der FROM-Klausel, während die SELECT-Klausel, die zum ersten Mal erscheint, verarbeitet fast zuletzt.

Jeder Schritt erzeugt eine virtuelle Tabelle, die als die Eingabe in der folgenden Stufe verwendet wird. Diese virtuellen Tabellen sind nicht verfügbar, an den Aufrufer (Client-Anwendung oder äußere Abfrage). Nur die von der letzten Stufe erzeugte Tabelle wird an den Aufrufer zurückgegeben. Wenn eine bestimmte Klausel in einer Abfrage nicht angegeben ist, wird der entsprechende Schritt übersprungen einfach.

Kurzbeschreibung der logischen Abfrageverarbeitung Phasen

Sie nicht zu viel Sorgen, wenn die Beschreibung der einzelnen Schritte scheint nicht viel Sinn für jetzt zu machen. Diese wird als Referenz zur Verfügung gestellt. Abschnitte, die nach dem Szenario Beispiel kommen die Schritte in viel mehr ins Detail abdecken.

  1. FROM: a. Cartesianischen Produkt (Kreuz join) zwischen den ersten beiden Tabellen in dem FROM-Klausel durchgeführt wird, und als Ergebnis wird die virtuelle Tabelle VT1 erzeugt

  2. ON: Die ON-Filter VT1 angewendet wird. Nur Zeilen, für die die <join_condition> TRUE ist an VT2 eingefügt.

  3. OUTER (zusammen): Wenn ein OUTER angegeben JOIN wird (im Gegensatz zu einem CROSS gegen JOIN oder ein INNER JOIN), Zeilen aus der erhaltenen Tabelle oder Tabellen, für die keine Übereinstimmung mit den Zeilen hinzugefügt aus gefunden VT2 als äußeren Reihen, Erzeugen VT3. Wenn mehr als zwei Tabellen in der FROM-Klausel erscheinen, werden die Schritte 1 bis 3 wiederholt zwischen dem Ergebnis der letzten Anwendung kommen und die nächste Tabelle in der FROM-Klausel bis alle Tabellen verarbeitet werden.

  4. WO: Die WHERE-Filter auf VT3 angewendet wird. Nur Zeilen, für die die <where_condition> TRUE ist an VT4 eingefügt.

  5. GROUP BY: Die Reihen von VT4 angeordnet sind, in Gruppen auf der Basis der Spaltenliste in der Klausel GROUP BY angegeben. VT5 erzeugt wird.

  6. CUBE | ROLLUP-: Supergruppen (Gruppen von Gruppen) mit den Reihen von VT5 hinzugefügt, VT6 Erzeugen

  7. .
  8. MIT: Die HAVING Filter wird auf VT6 angewendet. Nur Gruppen, für die die <having_condition> TRUE ist an VT7 eingefügt.

  9. SELECT:. Die SELECT-Liste verarbeitet wird, zu erzeugen VT8

  10. DISTINCT: Doppelte Zeilen aus VT8 entfernt. VT9 erzeugt wird.

  11. ORDER BY: Die Zeilen von VT9 sortiert werden nach der Spaltenliste in der ORDER BY-Klausel angegeben. Ein Cursor wird erzeugt (VC10).

  12. TOP: Die angegebene Anzahl oder der Prozentsatz der Zeilen ist von Anfang an von VC10 ausgewählt. Tabelle VT11 erzeugt wird und zu dem Anrufer.



     Daher (INNER JOIN) ON werden die Daten filtern (die Zähldaten von VT wird hier selbst reduziert werden), bevor WHERE-Klausel anwenden. Die nachfolgenden Joinbedingungen werden mit gefilterten Daten ausgeführt werden, die die Leistung verbessert. Danach nur die WHERE-Bedingung Filterbedingungen gelten.

(Anwenden von bedingten Anweisungen in ON / WHERE wird nicht viel Unterschied in wenigen Fällen machen. Dies ist abhängig, wie viele Tabellen, die Sie haben sich und die Anzahl der Zeilen in jeder Join-Tabellen)

Die implizite Join ANSI-Syntax ist schon älter, weniger offensichtlich und nicht zu empfehlen.

Darüber hinaus ist die relationale Algebra ermöglicht die Austauschbarkeit der Prädikate in der WHERE Klausel und die INNER JOIN, so auch INNER JOIN Abfragen mit WHERE Klauseln können die Prädikate vom Optimierer rearrranged haben.

Ich empfehle Ihnen, die Abfragen in den meisten readble Weise möglich schreiben.

Manchmal schließt dies die INNER JOIN Herstellung relativ „unvollständig“ und einige der Kriterien in der WHERE setzen einfach die Listen der Filterkriterien zu machen leichter wartbar.

Zum Beispiel statt:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Schreiben:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Aber es hängt natürlich davon ab.

Implizite verbindet (das ist, was Ihre erste Abfrage als bekannt ist) wird viel, viel mehr verwirrend, schwer lesbar ist, und schwer zu pflegen, sobald Sie beginnen müssen mehr Tabellen zur Abfrage hinzu. Stellen Sie sich vor, dass die gleiche Abfrage und Art Tun auf vier oder fünf verschiedene Tabellen miteinander verbindet ... es ist ein Alptraum.

Mit einer expliziten Join (Ihr zweites Beispiel) ist viel besser lesbar und leicht zu pflegen.

Ich werde auch darauf hinweisen, dass die ältere Syntax mehr unterliegt dem Irrtum. Wenn Sie Innen verwenden schließt sich ohne eine Klausel ON, erhalten Sie einen Syntaxfehler erhalten. Wenn Sie die ältere Syntax verwendet und in der where-Klausel einer der Joinbedingungen vergessen, werden Sie ein Cross-Join bekommen. Die Entwickler oft dieses Problem beheben, indem das Schlüsselwort distinct Hinzufügen (anstatt zur Festsetzung der Verbindung, weil sie noch nicht erkennen, die Verbindung selbst gebrochen ist), die das Problem heilen erscheinen, aber die Abfrage erheblich verlangsamen.

Zusätzlich zur Wartung, wenn Sie ein Cross-Join in der alten Syntax haben, wie wird der Betreuer wissen, wenn Sie eine haben sollen (es gibt Situationen, in denen Quer Joins benötigt werden), oder wenn es einen Unfall ist, die behoben werden sollte?

Lassen Sie mich darauf Sie auf diese Frage zu finden, warum die implizite Syntax schlecht ist, wenn man links schließt sich verwenden. Sybase * = zu Ansi Standard mit 2 verschiedenen äußeren Tabellen für gleiche innere Tabelle

Plus (persönlicher rant hier), der Standard mit dem expliziten verbindet, ist über 20 Jahre alt, was implizit bedeutet Join-Syntax für die 20 Jahre überholt wurde. Würden Sie Anwendungscode mit Syntax schreiben, die seit 20 Jahren veraltet ist? Warum wollen Sie Datenbank-Code zu schreiben, der ist?

Sie haben einen anderen Menschen lesbare Bedeutung.

jedoch in Abhängigkeit von den Abfrage-Optimierer, können sie die gleiche Bedeutung auf die Maschine haben.

Sie sollten immer Code lesbar sein.

Das heißt, wenn diese über eine integrierte in Beziehung ist, verwenden Sie die explizite beitreten. wenn Sie auf schwach bezogenen Daten passen, verwenden Sie die where-Klausel.

Der SQL: 2003-Standard geändert einige Präzedenzregeln ein so JOIN-Anweisung Vorrang vor einem „Komma“ join nimmt. Dies kann tatsächlich die Ergebnisse Ihrer Abfrage ändern, je nachdem wie es ist Setup. Diese verursachen einige Probleme für einige Leute, wenn MySQL 5.0.12 geschaltet den Standard einhalten.

So in Ihrem Beispiel, Ihre Fragen würden die gleiche Arbeit. Aber wenn Sie hinzugefügt, um eine dritte Tabelle: SELECT ... FROM table1, table2 JOIN table3 ON ... WHERE ...

Vor MySQL 5.0.12, Tabelle 1 und Tabelle 2 würde zuerst verbunden wird, dann table3. Jetzt (5.0.12 und auf), table2 und table3 werden zuerst verbunden, dann tabelle1. Es muss nicht immer die Ergebnisse ändern, aber es kann und man es nicht einmal erkennen kann.

ich nie mehr die „Komma“ Syntax verwenden, für Ihr zweites Beispiel entscheiden. Es ist viel besser lesbar wie auch immer, die JOIN Bedingungen sind mit der JOIN, nicht in eine separate Abfrage Abschnitt getrennt sind.

Ich weiß, du redest MySQL, aber trotzdem: In Oracle 9 explizite Verknüpfungen und implizit verbindet unterschiedliche Ausführungspläne erzeugen würde. AFAIK, dass wurde in Oracle gelöst 10+: es gibt nicht so Unterschied mehr.

ANSI-Join-Syntax auf jeden Fall mehr tragbar ist.

Ich werde durch ein Upgrade von Microsoft SQL Server, und ich möchte auch erwähnen, dass die = * und * = Syntax für Außen in SQL Server Joins nicht unterstützt wird (ohne Kompatibilitätsmodus) für SQL Server 2005 und höher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top