Database
 sql >> Datenbank >  >> RDS >> Database

So schreiben Sie komplexe Abfragen in SQL

Typische Abfragen im Tabellenformat SELECT * FROM reichen manchmal nicht aus. Wenn sich die Daten für eine Abfrage nicht in einer, sondern in mehreren Tabellen befinden oder wenn mehrere Selektionsparameter gleichzeitig angegeben werden müssen, benötigen Sie komplexere Abfragen.

In diesem Artikel wird erläutert, wie solche Abfragen erstellt werden, und Beispiele für komplexe SQL-Abfragen bereitgestellt.

Wie sieht eine komplexe Abfrage aus?

Lassen Sie uns zunächst die Bedingungen zum Erstellen der SQL-Abfrage definieren. Insbesondere müssen Sie die folgenden Selektionsparameter verwenden:

  • die Namen der Tabellen, aus denen Sie Daten extrahieren möchten;
  • die Werte von Feldern, die nach Änderungen an der Datenbank auf die ursprünglichen zurückgesetzt werden müssen;
  • die Beziehungen zwischen Tabellen;
  • die Probenahmebedingungen;
  • die zusätzlichen Auswahlkriterien (Einschränkungen, Art der Informationsdarstellung, Art der Sortierung).

Um das Thema besser zu verstehen, betrachten wir ein Beispiel, das die folgenden vier einfachen Tabellen verwendet. Die erste Zeile ist der Name der Tabelle, die bei komplexen Abfragen als Fremdschlüssel fungiert. Wir werden dies anhand eines Beispiels näher betrachten:

Jede Tabelle hat Zeilen, die sich auf einige andere Tabellen beziehen. Wir werden weiter erklären, warum es notwendig ist.

Sehen wir uns nun die grundlegende SQL-Abfrage an:

SELECT * FROM companies WHERE companies_name %STARTSWITH 'P';

Der %STARTSWITH Prädikat wählt Zeilen aus, die mit dem angegebenen Zeichen/den angegebenen Zeichen beginnen.

Das Ergebnis sieht so aus:

Betrachten wir nun eine komplexe SQL-Abfrage:

SELECT 
	companies.companies_name,
	SUM(CASE WHEN call.id IS NOT NULL THEN 1 ELSE 0 END) AS calls,
	AVG(ISNULL(DATEDIFF(SECOND, calls.start_time, calls.end_time),0)) AS avgdifference
FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id
GROUP BY 
	companies.id,
	companies.companies_name
HAVING AVG(ISNULL(DATEDIFF(SECOND, calls.start_time, calls.end_time),0)) > (SELECT AVG(DATEDIFF(SECOND, calls.start_time, calls.end_time)) FROM calls)
ORDER BY calls DESC, companies.id ASC;

Das Ergebnis ist die folgende Tabelle:

Die Tabelle zeigt die Unternehmen, die entsprechende Anzahl der Telefonate und deren ungefähre Dauer.

Außerdem werden nur die Firmennamen aufgeführt, bei denen die durchschnittliche Gesprächsdauer länger ist als die durchschnittliche Gesprächsdauer in anderen Unternehmen.

Was sind die Hauptregeln für die Erstellung komplexer SQL-Abfragen?

Versuchen wir, einen Mehrzweckalgorithmus zum Erstellen komplexer Abfragen zu erstellen.

Zunächst müssen Sie sich für die Tabellen entscheiden, die aus den Daten bestehen, die an der Abfrage teilnehmen.

Das obige Beispiel betrifft die Unternehmen und Anrufe Tische. Wenn die Tabellen mit den erforderlichen Daten nicht direkt miteinander in Beziehung stehen, müssen Sie auch die Zwischentabellen einbeziehen, die sie verbinden.

Aus diesem Grund verbinden wir auch Tabellen, wie z. B. Büros und Kunden , mit Fremdschlüsseln. Daher enthält jedes Ergebnis der Abfrage mit Tabellen aus diesem Beispiel immer die folgenden Zeilen:

SELECT 
	...
FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id
...;

After that, you must test the correctness of the behavior in the following part of the query:

SELECT * FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id;

Eine kombinierte Tabelle schlägt die drei wichtigsten Punkte vor:

  • Achten Sie auf die Liste der Felder nach SELECT. Der Vorgang des Lesens von Daten aus verknüpften Tabellen erfordert, dass Sie den Namen der zu verknüpfenden Tabelle im Namen angeben Feld.
  • Ihre komplexe Abfrage enthält immer die Haupttabelle (Unternehmen ). Die meisten Felder werden daraus gelesen. Die angehängte Tabelle verwendet in unserem Beispiel drei Tabellen – offices , Kunden , und Anrufe . Der Name wird nach dem JOIN-Operator ermittelt.
  • Außer dem Namen der zweiten Tabelle müssen Sie unbedingt die Bedingung für die Durchführung des Joins angeben. Wir werden diese Bedingung weiter besprechen.
  • Die Abfrage zeigt eine Tabelle mit einer großen Anzahl von Zeilen an. Er muss hier nicht veröffentlicht werden, da er Zwischenergebnisse anzeigt. Sie können die Ausgabe jedoch jederzeit selbst überprüfen. Dies ist sehr wichtig, da es hilft, Fehler im Endergebnis zu vermeiden.

Sehen wir uns nun den Teil der Abfrage an, der die Anrufdauer innerhalb jedes Unternehmens und zwischen allen Unternehmen vergleicht. Wir müssen die durchschnittliche Dauer aller Anrufe berechnen. Verwenden Sie die folgende Abfrage:

SELECT AVG(DATEDIFF(SECOND, calls.start_time, calls.end_time)) FROM calls

Beachten Sie, dass wir das DATEDIFF verwendet haben Funktion, die die Differenz zwischen den angegebenen Perioden ausgibt. In unserem Fall beträgt die durchschnittliche Gesprächsdauer 335 Sekunden.

Jetzt fügen wir der Abfrage Daten zu Anrufen aller Unternehmen hinzu.

SELECT 
	companies.companies_name,
	SUM(CASE WHEN calls.id IS NOT NULL THEN 1 ELSE 0 END) AS calls,
	AVG(ISNULL(DATEDIFF(SECOND, calls.start_time, calls.end_time),0)) AS avgdifference
FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id
GROUP BY 
	companies.id,
	companies.companies_name
ORDER BY calls DESC, companies.id ASC;

In dieser Abfrage

  • SUMME (FALL WENN anrufe.id NICHT NULL DANN 1 SONST 0 ENDE IST) – Um unnötige Operationen zu vermeiden, fassen wir nur bestehende Anrufe zusammen – wenn die Anzahl der Anrufe in einem Unternehmen nicht Null ist. Dies ist sehr wichtig in großen Tabellen mit möglichen Nullwerten.
  • AVG (ISNULL (DATEDIFF (SECOND, anrufe.start_time, anrufe.end_time), 0)) – Die Abfrage ist identisch mit der AVG-Abfrage oben. Hier verwenden wir jedoch die ISNULL Operator, der NULL durch 0 ersetzt. Er ist notwendig für Unternehmen, die überhaupt keine Anrufe haben.

Unsere Ergebnisse:

Wir sind fast fertig. Die obige Tabelle zeigt die Liste der Unternehmen, die entsprechende Anzahl der Anrufe für jedes von ihnen und die durchschnittliche Anrufdauer in jedem von ihnen.

Jetzt müssen Sie nur noch die Zahlen aus der letzten Spalte mit der durchschnittlichen Dauer aller Anrufe aller Unternehmen (335 Sekunden) vergleichen.

Wenn Sie die Abfrage eingeben, die wir ganz am Anfang vorgestellt haben, fügen Sie einfach das HAVING hinzu Teil, Sie werden bekommen, was Sie brauchen.

Wir empfehlen dringend, Kommentare zu jeder Zeile hinzuzufügen, damit Sie in Zukunft nicht verwirrt werden, wenn Sie einige vorhandene komplexe SQL-Abfragen korrigieren müssen.

Abschließende Gedanken

Obwohl jede komplexe SQL-Abfrage einen individuellen Ansatz erfordert, sind einige Empfehlungen für die Vorbereitung der meisten solcher Abfragen geeignet.

  • festlegen, welche Tabellen an der Abfrage teilnehmen;
  • komplexe Abfragen aus einfacheren Teilen erstellen;
  • prüfen Sie die Genauigkeit der Abfragen sequentiell, in Teilen;
  • Testen Sie die Genauigkeit Ihrer Abfrage mit kleineren Tabellen;
  • Schreiben Sie ausführliche Kommentare zu jeder Zeile, die den Operanden enthält, und verwenden Sie dabei die Symbole „-“.

Spezielle Werkzeuge machen diese Arbeit viel einfacher. Unter ihnen empfehlen wir die Verwendung des Abfragegenerators – ein visuelles Tool, mit dem selbst die komplexesten Abfragen viel schneller in einem visuellen Modus erstellt werden können. Dieses Tool ist als eigenständige Lösung oder als Teil des vielseitigen dbForge Studio für SQL Server erhältlich.

Wir hoffen, dass dieser Artikel Ihnen geholfen hat, dieses spezielle Problem zu klären.