14th Mar 2023 33 Leseminuten Top 27 Interviewfragen für fortgeschrittenes SQL mit Antworten Tihomir Babic Jobs und Karriere SQL-Interviewfragen Inhaltsverzeichnis 1. was ist ein JOIN in SQL? 2) Was ist der Unterschied zwischen INNER JOIN, LEFT JOIN, RIGHT JOIN und FULL JOIN? 3. was ist ein CROSS JOIN? 4 Was ist ein Self-Join in SQL? 5. zwei Tabellen mit einem zweispaltigen JOIN verbinden 6. zwei Tabellen mit einem Nicht-Gleichheits-Join verbinden 7. was macht DISTINCT? 8. was bewirkt GROUP BY in SQL? 9 Wie filtert man GROUP BY-Gruppen? 10. was ist der Unterschied zwischen WHERE und HAVING? 11 Was ergibt die folgende Abfrage, die versucht, NULLs zu filtern? 12. schreiben Sie eine Abfrage, die die Anzahl der Songs nach Künstler ermittelt. Verwenden Sie LEFT JOIN und COUNT(). 13. was ist der Unterschied zwischen JOIN und UNION? 14. was ist der Unterschied zwischen UNION und UNION ALL? 15 Was ist eine Unterabfrage in SQL? 16 Schreiben Sie eine Abfrage, die Verkäufer und ihre monatlichen Umsatzdaten über ihrem persönlichen Umsatzdurchschnitt zurückgibt. Verwenden Sie eine korrelierte Unterabfrage. 17 Was sind Fensterfunktionen in SQL? 18. was ist der Unterschied zwischen Fensterfunktionen und GROUP BY? 19. welche Fensterfunktionen kennen Sie? 20 Wie erstellt man eine Rangliste in SQL? 21. was ist der Unterschied zwischen RANK() und DENSE_RANK()? 22. die obersten n Zeilen in SQL mit einer Fensterfunktion und einem CTE finden. 23. die Differenz zwischen zwei Zeilen (Delta) berechnen mit Fensterfunktionen 24. Fensterfunktionen verwenden, um eine laufende Summe zu berechnen 25. einen gleitenden Durchschnitt finden mit Fensterfunktionen 26. was ist der Unterschied zwischen ROWS und RANGE? 27 Verwenden Sie eine rekursive Abfrage, um alle Mitarbeiter unter einem bestimmten Manager zu finden. Sind Sie bereit, die SQL-Interviewfragen zu meistern? Wo kann ein SQL-Experte einen umfassenden Leitfaden für fortgeschrittene SQL-Interview-Fragen finden? Die kürzeste Antwort lautet: hier! Wir haben die 27 wichtigsten SQL-Fragen ausgewählt und sie für Sie beantwortet. Die Vorbereitung auf ein SQL-Vorstellungsgespräch ist nicht einfach, vor allem, wenn Ihr Job fortgeschrittene SQL-Kenntnisse erfordert. Dieser Artikel enthält die 27 am häufigsten gestellten Fragen zu fortgeschrittenen SQL-Interviews sowie ausführliche Antworten und weiterführende Informationen. Wir werden diese vier Hauptkonzepte und einige weitere durchgehen: JOINs GROUP BY, WHERE, und HAVING CTEs (Common Table Expressions) und rekursive Abfragen Fensterfunktionen Am besten frischen Sie Ihre fortgeschrittenen SQL-Kenntnisse auf, indem Sie an unserem interaktiven Fortgeschrittenes SQL Kurs. Er enthält über 300 praktische Übungen zu Fensterfunktionen, Common Table Expressions, rekursiven Funktionen und mehr. Lassen Sie uns diese Fragen ohne Umschweife frontal angehen! 1. was ist ein JOIN in SQL? JOIN ist ein SQL-Befehl, mit dem Sie zwei oder mehr Tabellen miteinander verbinden können. Dies geschieht über eine gemeinsame Spalte (d. h. eine Spalte, die in beiden Tabellen die gleichen Werte hat), die es ermöglicht, Daten aus zwei oder mehr Tabellen gleichzeitig zu verwenden. Die Verknüpfung von Tabellen in SQL ist aufgrund der Beschaffenheit relationaler Datenbanken unerlässlich: Daten werden in Tabellen atomisiert, wobei jede Tabelle nur einen Teil der in der Datenbank verfügbaren Daten enthält. Wir werden zwei Tabellen verwenden, um zu zeigen, wie das funktioniert. Die erste Tabelle ist football_players. idfirst_namelast_namenational_team_idgames_played 1GianfrancoZola135 2Virgilvan Dijk253 3MarcusRashford351 4KylianMbappé566 5PhilFoden322 6Frenkiede Jong222 7MarioBalotelli136 8ErlingHaaland623 Die zweite ist national_team. idcountry 1Italy 2Netherlands 3England 4Croatia Hier ist eine Abfrage, die zwei Tabellen miteinander verbindet: SELECT fp.id, first_name, last_name, national_team_id, country, games_played FROM football_players fp JOIN national_team nt ON fp.national_team_id = nt.id ORDER BY fp.id; Sie wählt Spalten aus beiden Tabellen aus. Um sie zu verbinden, verweisen wir zuerst auf eine Tabelle in der FROM Klausel. Danach folgt JOIN, und danach kommt die zweite Tabelle. Mit der Klausel ON geben wir die Bedingung an, mit der die Tabellen verbunden werden: national_team_id in der Tabelle football_players Tabelle muss gleich der Spalte id in der national_team Tabelle. Die Ausgabe der Abfrage lautet: idfirst_namelast_namenational_team_idcountrygames_played 1GianfrancoZola1Italy35 2Virgilvan Dijk2Netherlands53 3MarcusRashford3England51 5PhilFoden3England22 6Frenkiede Jong2Netherlands22 7MarioBalotelli1Italy36 INNER JOIN ist eine der zahlreichen eindeutigen Verknüpfungen in SQL. Ihr Merkmal ist, dass sie nur Daten aus den verbundenen Tabellen zurückgibt, bei denen die Verbindungsbedingung wahr ist. Hier finden Sie weitere Einzelheiten über die Funktionsweise des SQL INNER JOIN. 2) Was ist der Unterschied zwischen INNER JOIN, LEFT JOIN, RIGHT JOIN und FULL JOIN? Es gibt verschiedene Arten von Joins in SQL. Die am häufigsten verwendeten Joins sind INNER JOIN, LEFT JOIN, RIGHT JOIN und FULL JOIN. LEFT JOIN, RIGHT JOIN und FULL JOIN sind so genannte äußere Joins. JOIN (auch bekannt als INNER JOIN) ist ein innerer Join. In diesem Fall bedeutet "inner", dass nur die Zeilen aus beiden Tabellen zurückgegeben werden, die die Join-Bedingung erfüllen; bei "outer joins" werden alle Zeilen in einer Tabelle und die passenden Zeilen in der/den anderen Tabelle(n) zurückgegeben. Die Ausnahme ist FULL JOIN, die alle Zeilen aus beiden Tabellen zurückgibt. Hier ist das Ergebnis von INNER JOIN aus dem vorherigen Beispiel. Lassen Sie es uns hier noch einmal sehen. Auf diese Weise wird es einfacher, den Unterschied zwischen den verschiedenen Joins zu erkennen. idfirst_namelast_namenational_team_idcountrygames_played 1GianfrancoZola1Italy35 2Virgilvan Dijk2Netherlands53 3MarcusRashford3England51 5PhilFoden3England22 6Frenkiede Jong2Netherlands22 7MarioBalotelli1Italy36 LEFT JOIN gibt alle Daten aus der linken Tabelle (d. h. der ersten Tabelle, die vor\links vom Schlüsselwort JOIN aufgeführt ist) und nur die übereinstimmenden Zeilen aus der rechten Tabelle (der zweiten Tabelle, die nach\rechts vom Schlüsselwort JOIN aufgeführt ist) zurück. Wenn es in der rechten Tabelle keine übereinstimmenden Daten gibt, werden die fehlenden Werte als NULLs angezeigt. Hier ist die gleiche Abfrage mit LEFT JOIN als Ersatz für INNER JOIN: SELECT fp.id, first_name, last_name, national_team_id, country, games_played FROM football_players fp LEFT JOIN national_team nt ON fp.national_team_id = nt.id ORDER BY fp.id; Die linke Tabelle ist hier football_players, und die rechte Tabelle ist national_team. Wie zu erwarten war, ist die Ausgabe unterschiedlich: idfirst_namelast_namenational_team_idcountrygames_played 1GianfrancoZola1Italy35 2Virgilvan Dijk2Netherlands53 3MarcusRashford3England51 4KylianMbappé5NULL66 5PhilFoden3England22 6Frenkiede Jong2Netherlands22 7MarioBalotelli1Italy36 8ErlingHaaland6NULL23 Alle Fußballspieler aus der linken Tabelle sind hier zu finden. Allerdings haben Kylian Mbappe und Erling Haaland kein passendes Land in der rechten Tabelle, daher gibt es NULLs in der Spalte country für diese Spieler. Diese Zeilen waren im Ergebnis von INNER JOIN nicht vorhanden. Sie wurden durch die LEFT JOIN hinzugefügt. RIGHT JOIN macht das Gegenteil: Es gibt alle Daten aus der rechten Tabelle und nur die passenden Daten aus der linken Tabelle zurück. Wenn es keine übereinstimmenden Daten in der linken Tabelle gibt, werden die fehlenden Werte als NULLs angezeigt. Hier ist der Code: SELECT fp.id, first_name, last_name, national_team_id, country, games_played FROM football_players fp RIGHT JOIN national_team nt ON fp.national_team_id = nt.id ORDER BY fp.id; Alles bleibt gleich, außer dass wir RIGHT JOIN anstelle von LEFT JOIN verwenden. Dies ist die Ausgabe: idfirst_namelast_namenational_team_idcountrygames_played 1GianfrancoZola1Italy35 2Virgilvan Dijk2Netherlands53 3MarcusRashford3England51 5PhilFoden3England22 6Frenkiede Jong2Netherlands22 7MarioBalotelli1Italy36 NULLNULLNULLNULLCroatiaNULL Wir haben jetzt alle Nationalmannschaften und ihre Spieler. Aber Sie können sehen, dass ein Land (Kroatien) keine Spieler in der linken Tabelle hat. Die Spielerspalten für Kroatien sind mit NULLen gefüllt. FULL JOIN gibt alle Daten aus allen verbundenen Tabellen aus. Wenn in der entsprechenden Tabelle keine übereinstimmenden Daten vorhanden sind, werden die fehlenden Werte wieder als NULL angezeigt. Auch hier ändern wir den Join-Typ in der Abfrage: SELECT fp.id, first_name, last_name, national_team_id, country, games_played FROM football_players fp FULL JOIN national_team nt ON fp.national_team_id = nt.id ORDER BY fp.id; Es werden alle Daten aus beiden Tabellen zurückgegeben. Alle nicht übereinstimmenden Daten werden durch NULLs ersetzt. Alle Spieler sind im Ergebnis enthalten, auch wenn sie kein entsprechendes Land in der anderen Tabelle haben. Alle Länder sind im Ergebnis enthalten, auch wenn sie keine Spieler in der football_player Tabelle haben. Das Ergebnis FULL JOIN ist die Vereinigung von LEFT JOIN und RIGHT JOIN: idfirst_namelast_namenational_team_idcountrygames_played 1GianfrancoZola1Italy35 2Virgilvan Dijk2Netherlands53 3MarcusRashford3England51 4KylianMbappé5NULL66 5PhilFoden3England22 6Frenkiede Jong2Netherlands22 7MarioBalotelli1Italy36 8ErlingHaaland6NULL23 NULLNULLNULLNULLCroatiaNULL Weitere Informationen finden Sie in dem Artikel über die verschiedenen JOIN-Typen. Für eine schnelle Auffrischung können Sie auch unser SQL-JOINs Cheat Sheet lesen. 3. was ist ein CROSS JOIN? Ein CROSS JOIN ist ein weiterer in SQL verfügbarer Verknüpfungstyp. Er gibt ein kartesisches Produkt zurück. Das bedeutet, dass ein CROSS JOIN jede Zeile aus der ersten Tabelle kombiniert mit jeder Zeile aus der zweiten Tabelle zurückgibt. Er wird nicht sehr häufig verwendet. Aber wenn Sie versucht sind, es zu benutzen, überlegen Sie es sich zweimal. Die Rückgabe aller Zeilenkombinationen kann einige Zeit dauern - wenn die Abfrage überhaupt beendet wird! Lassen Sie uns als Beispiel die Tabellen aus den beiden vorherigen Fragen verwenden. Um die Abfrage zu schreiben, verwenden Sie das Schlüsselwort CROSS JOIN. Da dies ein Join-Typ ist, der alle Zeilenkombinationen aus allen Tabellen zurückgibt, gibt es keine ON Klausel. Schauen Sie sich das an: SELECT fp.id, first_name, last_name, national_team_id, country, games_played FROM football_players fp CROSS JOIN national_team nt; Hier ist die Ausgabe. Alle Spieler in der Tabelle football_players Tabelle sind mit allen Ländern in der national_team Tabelle aufgelistet. idfirst_namelast_namenational_team_idcountrygames_played 1GianfrancoZola1Italy35 2Virgilvan Dijk2Italy53 3MarcusRashford3Italy51 4KylianMbappé5Italy66 5PhilFoden3Italy22 6Frenkiede Jong2Italy22 7MarioBalotelli1Italy36 8ErlingHaaland6Italy23 1GianfrancoZola1Netherlands35 2Virgilvan Dijk2Netherlands53 3MarcusRashford3Netherlands51 4KylianMbappé5Netherlands66 5PhilFoden3Netherlands22 6Frenkiede Jong2Netherlands22 7MarioBalotelli1Netherlands36 8ErlingHaaland6Netherlands23 1GianfrancoZola1England35 2Virgilvan Dijk2England53 3MarcusRashford3England51 4KylianMbappé5England66 5PhilFoden3England22 6Frenkiede Jong2England22 7MarioBalotelli1England36 8ErlingHaaland6England23 1GianfrancoZola1Croatia35 2Virgilvan Dijk2Croatia53 3MarcusRashford3Croatia51 4KylianMbappé5Croatia66 5PhilFoden3Croatia22 6Frenkiede Jong2Croatia22 7MarioBalotelli1Croatia36 8ErlingHaaland6Croatia23 Mehr über CROSS JOIN erfahren Sie in dieser illustrierten Anleitung zum SQL CROSS JOIN. 4 Was ist ein Self-Join in SQL? Wie Sie wahrscheinlich schon vermuten, liegt ein Self-Join vor, wenn die Tabelle mit sich selbst verbunden wird. Es ist wichtig zu wissen, dass es sich dabei nicht um einen speziellen SQL-Befehl handelt: Jeder JOIN -Typ kann verwendet werden, um eine Tabelle mit sich selbst zu verbinden. Die Verknüpfung erfolgt wie jede andere JOIN, aber dieses Mal verweisen Sie auf beiden Seiten des JOIN Schlüsselworts auf dieselbe Tabelle. Self-joining ist besonders nützlich, wenn eine Tabelle einen Fremdschlüssel hat, der auf ihren Primärschlüssel verweist. Damit können Sie hierarchische Daten abfragen, z. B. Familienstammbäume oder die Organisationshierarchie eines Unternehmens. Es ist auch hilfreich, wenn Sie Wertepaare finden wollen. Im folgenden Beispiel suchen wir nach Spielern der gleichen Nationalmannschaft: SELECT fp1.id, fp1.first_name, fp1.last_name, fp1.national_team_id, fp2.id AS id_2, fp2.first_name AS first_name_2, fp2.last_name AS last_name_2, fp2.national_team_id as national_team_id_2 FROM football_players fp1 JOIN football_players fp2 ON fp1.id <> fp2.id AND fp1.national_team_id = fp2.national_team_id; Self-joining bedeutet, dass Sie anstelle von zwei Tabellen dieselbe Tabelle zweimal angeben: einmal in der FROM -Klausel und einmal nach der JOIN -Klausel. Da Sie dieselbe Tabelle zweimal verwenden, müssen Sie Aliasnamen für die Tabellen verwenden. Jedem Vorkommen der Tabelle sollte ein eindeutiger Alias gegeben werden (fp1, fp2 in unserer Abfrage), damit klar ist, auf welches Vorkommen der Tabelle wir uns beziehen. Wir fügen Spieler aus derselben Nationalmannschaft zusammen (ihre national_team_id Werte sind gleich). Wir wollen jedoch nicht einen Spieler mit sich selbst auflisten, also schließen wir den Fall aus, dass fp1.id und fp2.id gleich sind. Die Ausgabe der Abfrage ist diese: idfirst_namelast_namenational_team_idid_2first_name_2last_name_2national_team_id_2 1GianfrancoZola17MarioBalotelli1 2Virgilvan Dijk26Frenkiede Jong2 3MarcusRashford35PhilFoden3 5PhilFoden33MarcusRashford3 6Frenkiede Jong22Virgilvan Dijk2 7MarioBalotelli11GianfrancoZola1 Sie können die Spalten national_team_id aus beiden Tabellen verwenden, um zu bestätigen, dass Gianfranco Zola und Mario Balotelli tatsächlich für dieselbe Mannschaft gespielt haben. Mehr dazu erfahren Sie in unserem Artikel über Self-Join-Beispiele. 5. zwei Tabellen mit einem zweispaltigen JOIN verbinden Sie haben zwei Tabellen. Die erste Tabelle ist employee, die die folgenden Daten enthält: idfirst_namelast_name 1SteveBergman 2SteveJohnson 3SteveKing Die zweite Tabelle ist customerdie die folgenden Daten enthält: idfirst_namelast_name 1AnnColeman 2SteveBergman 3SteveYoung 4DonnaWinter 5SteveKing Ihre Aufgabe ist es, alle Mitarbeiter zu finden, die auch Kunden des Unternehmens sind. Leider können Sie die Spalte id nicht verwenden, da es sich um die Mitarbeiter-ID in einer Tabelle und die Kunden-ID in einer anderen handelt. Mit anderen Worten, es gibt keine einzelne Spalte in einer Tabelle, die auf die andere verweist. Die Lösung besteht darin, Tabellen über den Vor- und Nachnamen zu verknüpfen, d. h. eine zweispaltige JOIN zu verwenden. Der folgende Code verbindet die Tabellen zunächst über den Vornamen. Danach wird mit dem Schlüsselwort AND die zweite Verknüpfungsbedingung festgelegt, nämlich der Nachname. Auf diese Weise erhalten Sie Daten aus beiden Tabellen, bei denen die Kombination aus Vorname und Nachname gleich ist. Hätten wir nur eine dieser Spalten verwendet, hätten wir möglicherweise die falschen Daten erhalten, da Mitarbeiter und Kunden denselben Vornamen, aber unterschiedliche Nachnamen haben können (oder umgekehrt). Hier ist die Abfrage: SELECT e.first_name, e.last_name FROM employee e JOIN customer c ON e.first_name = c.first_name AND e.last_name = c.last_name; Hier ist die Code-Ausgabe..: first_namelast_name SteveBergman SteveKing Das Ergebnis zeigt, dass Steve Bergman und Steve King sowohl Mitarbeiter als auch Kunden des Unternehmens sind. 6. zwei Tabellen mit einem Nicht-Gleichheits-Join verbinden Bisher haben wir Equi-Joins verwendet: Joins, bei denen die Bedingung ON ein Gleichheitszeichen enthält. Der Nicht-Gleichheits-Join hingegen ist ein Join, der eine Nicht-Gleichheits-Bedingung in der ON Klausel enthält. Diesmal haben wir Daten über mobile Benutzer und ihre Datennutzung. Die erste Tabelle ist mobile_userdie Mobilfunknutzer und ihr monatliches mobiles Datenlimit in MB anzeigt: idfirst_namelast_namemobile_data_limit 1MichaelWatson5,000 2NicoleGomez10,000 3SamStone8,000 Die zweite Tabelle ist data_usagedie den tatsächlichen monatlichen Datenverbrauch des Benutzers in MB anzeigt: idmobile_user_iddata_usedperiod 114,9872022_10 226,8752022_10 3312,5472022_10 415,0372022_11 5211,1112022_11 634,8972022_11 Die Aufgabe besteht darin, alle Daten zu finden, bei denen die tatsächliche Nutzung über dem monatlichen Limit lag. Wir möchten den Vor- und Nachnamen des Benutzers, das monatliche Limit, die tatsächlich genutzten Daten und den Zeitraum sehen. Die Lösung ist die Verwendung der nicht-gleichnamigen Verknüpfung, wie unten gezeigt: SELECT first_name, last_name, mobile_data_limit, data_used, period FROM mobile_user mu JOIN data_usage du ON mu.id = du.mobile_user_id AND mobile_data_limit < data_used; Die Abfrage wählt alle erforderlichen Informationen aus zwei Tabellen aus. Die Tabellen werden mit INNER JOIN verknüpft. Zunächst werden sie verbunden, wenn die Benutzer-ID dieselbe ist. Dann fügen wir die zweite Bedingung nach dem Schlüsselwort AND hinzu. Hier haben wir eine Nicht-Gleichheitsbedingung, die uns Daten liefert, bei denen das Limit unter der monatlichen Nutzung liegt. Das Ergebnis können Sie unten sehen: first_namelast_namemobile_data_limitdata_usedperiod SamStone8,00012,5472022_10 MichaelWatson5,0005,0372022_11 NicoleGomez10,00011,1112022_11 Wenn Sie interessiert sind, finden Sie hier weitere Beispiele für ungleiche Verknüpfungen. 7. was macht DISTINCT? DISTINCTDer Zweck von DISTINCT besteht im Allgemeinen darin, doppelte Werte zu entfernen. Oder, anders ausgedrückt, um eindeutige Werte in der Ausgabe Ihrer Abfrage anzuzeigen. Stellen Sie sich vor, Sie arbeiten mit dieser loans Tabelle, die Darlehens-IDs und deren Laufzeiten in Monaten zeigt. loan_idloan_duration 10011260 10020560 10020848 100333120 10035748 100398120 Verschiedene Darlehen können die gleiche Laufzeit haben, also möchten Sie die Liste der möglichen Darlehenslaufzeiten extrahieren. Dies können Sie mit DISTINCT tun: SELECT DISTINCT loan_duration FROM loans ORDER BY loan_duration; Die Ausgabe zeigt, dass es Darlehen mit Laufzeiten von 48, 60 und 120 Monaten gibt: loan_duration 48 60 120 DISTINCT kann in SELECT mit einer Spalte verwendet werden, um nur die eindeutigen Werte dieser Spalte anzuzeigen, wie im obigen Beispiel. Wenn es in SELECT mit mehreren Spalten verwendet wird, zeigt die Ausgabe die eindeutigen Kombinationen all dieser Spalten an. Sie können DISTINCT auch mit Aggregatfunktionen verwenden. Wenn Sie das tun, wird Ihre Abfrage doppelte Aggregationsergebnisse eliminieren. Beispiele für diese Verwendungen finden Sie in unserem Artikel über die Rolle von DISTINCT in SQL. 8. was bewirkt GROUP BY in SQL? GROUP BY ist eine SQL-Klausel, mit der Daten auf der Grundlage eines oder mehrerer gemeinsamer Werte in Gruppen geordnet werden. Sie wird am häufigsten mit Aggregatfunktionen verwendet; diese Kombination liefert aggregierte Daten für jede Gruppe. Es ist jedoch wichtig zu wissen, dass die Verwendung von Aggregatfunktionen innerhalb der GROUP BY Klausel nicht erlaubt ist. Die allgemeine GROUP BY Syntax lautet: SELECT column_1, column_2, …, FROM table_name WHERE … GROUP BY column_1, column_2 HAVING … ORDER BY column_1, column_2; Angenommen, es gibt die Tabelle salaries: idfirst_namelast_namesalarydepartment 1NicholasPoirot4,798.44IT 2SamanthaWolf5,419.24IT 3StewartJohnsons5,419.24IT 4JackieBiden8,474.54Sales 5MarkHamilton10,574.84Sales 6MarianaCosta9,747.54Sales 7PaulStewart3,498.12Accounting 8MaryRutte4,187.23Accounting 9ThomasSchwarz3,748.55Accounting Wir verwenden GROUP BY und AVG(), um das Durchschnittsgehalt nach Abteilung zu ermitteln: SELECT department, AVG(salary) AS average_salary FROM salaries GROUP BY department; Wir wollen die Abteilungen sehen, also wählen wir diese Spalte aus. Um das Durchschnittsgehalt zu berechnen, wenden wir die Funktion AVG() auf die Spalte salary an. Alle in GROUP BY aufgeführten Spalten definieren die Datengruppen. In unserem Beispiel werden die Gruppen durch die Spalte Abteilung definiert: Wir berechnen das Durchschnittsgehalt für jede Abteilung. Unsere Datengruppierung und -aggregation sieht folgendermaßen aus: departmentaverage_salary Accounting3,811.30 Sales9,598.97 IT5,212.31 Das Durchschnittsgehalt in der Buchhaltung beträgt 3.811,30. Die Durchschnittsgehälter in den beiden anderen Abteilungen betragen 9.598,97 bzw. 5.212,31. Wenn Sie eine Abfrage schreiben, muss GROUP BY immer nach WHERE, aber vor der Klausel HAVING stehen. Mehr darüber erfahren Sie in diesem Artikel über GROUP BY in SQL. 9 Wie filtert man GROUP BY-Gruppen? Sobald Sie die Gruppen erhalten haben, die Sie in GROUP BY angegeben haben, möchten Sie sie manchmal filtern. Der Schlüssel dazu liegt in der Syntax aus der vorherigen Frage. Die Klausel, mit der Sie Gruppen filtern können, lautet HAVING. Nachdem die Filterkriterien in HAVING angegeben wurden, gibt die Abfrage alle Daten zurück, die die Kriterien erfüllen. Alle anderen Daten werden herausgefiltert. So funktioniert es mit den Daten aus der vorherigen Frage, wenn wir nur Abteilungen mit einem Durchschnittsgehalt unter 5.500 Dollar anzeigen wollen. SELECT department, AVG(salary) AS average_salary FROM salaries GROUP BY department HAVING AVG(salary) < 5500; Der Code ist dem in der vorigen Frage sehr ähnlich. Der Unterschied ist die HAVING Klausel. Wir verwenden sie, um die Ergebnisse zu filtern und nur Abteilungen mit Gehältern unter 5.500 Dollar anzuzeigen. Der Code gibt Folgendes zurück: departmentaverage_salary Accounting3,811.30 IT5,212.31 Die Abteilung, die in der Ausgabe fehlt, ist der Vertrieb, da ihr Durchschnittsgehalt 9.598,97 beträgt. Weitere praktische Beispiele für diese Klausel finden Sie in diesem Artikel, der HAVING in SQL erklärt. 10. was ist der Unterschied zwischen WHERE und HAVING? Wenn Sie die Antworten auf die beiden vorherigen Fragen kennen, wissen Sie wahrscheinlich auch die Antwort auf diese Frage. Der Hauptunterschied besteht darin, dass WHERE zum Filtern von Daten verwendet wird , bevor sie gruppiert werden. Seine Position in der Anweisung SELECT zeigt dies: Er steht vor GROUP BY. Aufgrund seines Zwecks sind in WHERE keine Aggregatfunktionen erlaubt. HAVINGDie Anweisung GROUP BY dient dag egen zum Filtern von Daten nach der Gruppierung; deshalb wird sie nach verwendet. Auch HAVING lässt Bedingungen zu, die Aggregatfunktionen enthalten. Am besten lernen Sie die Unterscheidung, indem Sie diesen Artikel über WHERE vs. HAVING in SQL lesen. 11 Was ergibt die folgende Abfrage, die versucht, NULLs zu filtern? Diese Art von Frage wird Ihnen in Ihrem SQL-Interview für Fortgeschrittene häufig gestellt: Sie erhalten einen Code und müssen beschreiben, was die Abfrage zurückgibt. Obwohl das Schreiben und Lesen von SQL-Code Hand in Hand gehen, ist es doch etwas anderes, wenn Sie den Code analysieren müssen, den jemand anderes geschrieben hat. Sie haben Daten in der Tabelle contributors: idfirst_namelast_namestart_datetermination_date 1ValeriaBogdanov2022-10-11NULL 2NicholasBertolucci2022-04-072022-11-11 3MathildeBauman2022-05-252022-10-01 4TrevorTrucks2022-01-28NULL 5MariaSzabo2022-03-15NULL Was wird dieser Code zurückgeben? SELECT first_name, last_name, start_date, termination_date FROM contributors WHERE termination_date != '2022-10-01'; Wenn Sie antworten, dass er alle Zeilen außer ID = 3 zurückgeben wird, liegen Sie falsch! Dies ist eine Art Trickfrage. Wenn Sie die Bedingung WHERE lesen, könnten Sie sie wie folgt lesen: Alle Daten zurückgeben, bei denen das Enddatum von 2022-10-01 verschieden ist. Wenn man sich die Tabelle ansieht, könnte man meinen, dass es sich um alle Zeilen außer einer handelt. Das ist es auch, aber nicht für SQL! Wie Sie sehen können, gibt es drei Zeilen mit NULL Werten. Für SQL ist NULL nicht gleich einem Wert, sondern ein Nicht-Wert. Wenn Sie also die Bedingung in WHERE so einrichten, schließen Sie alle Datumsangaben aus, die nicht gleich dem Wert 2022-10-01 und NULL sind. Hier ist die Ausgabe als Beweis: first_namelast_namestart_datetermination_date NicholasBertolucci2022-04-072022-11-11 Sie können mehr über diesen und andere Vergleichsoperatoren, die mit NULL verwendet werden, erfahren. 12. schreiben Sie eine Abfrage, die die Anzahl der Songs nach Künstler ermittelt. Verwenden Sie LEFT JOIN und COUNT(). Angenommen, Sie haben zwei Tabellen: artist und song. Hier sind die artist Daten: idartist_name 1Prince 2Jimi Hendrix 3Santana 4Otis Redding 5Lou Rawls Nachfolgend die song Daten: idartist_idsong_title 11Purple Rain 22Purple Haze 33Europa 41Cream 51Bambi 61Why You Wanna Treat Me So Bad? 72Spanish Castle Magic 83Taboo 93Incident at Neshabur 103Flor D' Luna Sie müssen LEFT JOIN und COUNT() verwenden, um alle Künstler, ihre IDs und die Anzahl ihrer Lieder in der Datenbank zu finden. Sie könnten versucht sein, diese Lösung vorzuschlagen: SELECT a.id, artist_name, COUNT(*) AS number_of_songs FROM artist a LEFT JOIN song s ON a.id = s.artist_id GROUP BY a.id, artist_name ORDER BY a.id; Werfen wir einen Blick auf die Ausgabe: idartist_namenumber_of_songs 1Prince4 2Jimi Hendrix2 3Santana4 4Otis Redding1 5Lou Rawls1 Die Ausgabe zeigt alle Künstler an; das ist in Ordnung. Allerdings ist die Anzahl der Songs für Otis Redding und Lou Rawls eins, was falsch ist! Werfen Sie einen Blick auf die Tabelle songund Sie werden sehen, dass es keine Künstler-IDs gibt, die gleich 4 oder 5 sind. Was ist falsch gelaufen? Wenn Sie COUNT(*) mit LEFT JOIN verwenden, zählt die Aggregatfunktion alle nicht übereinstimmenden Werte (NULLs). Deshalb zeigte das Ergebnis je einen Song für Otis Redding und Lou Rawls an, obwohl sie keine Songs in der Tabelle haben. COUNT(*) wird verwendet, um alle Zeilen zu zählen. Um eine korrekte Antwort zu geben, sollten Sie stattdessen COUNT(song_title) verwenden. SELECT a.id, artist_name, COUNT(song_title) AS number_of_songs FROM artist a LEFT JOIN song s ON a.id = s.artist_id GROUP BY a.id, artist_name ORDER BY a.id; Mit diesem Code erhalten Sie die richtige Ausgabe: idartist_namenumber_of_songs 1Prince4 2Jimi Hendrix2 3Santana4 4Otis Redding0 5Lou Rawls0 Die Anzahl der Songs von Prince, Jimi Hendrix und Santana ist die gleiche geblieben wie in der vorherigen Ausgabe. Die Anzahl der Lieder der beiden anderen Künstler ist jetzt jedoch Null, und das ist die richtige Zahl. 13. was ist der Unterschied zwischen JOIN und UNION? JOIN ist eine SQL-Klausel, mit der zwei oder mehr Tabellen verbunden werden. Sie ermöglicht die Verwendung von Daten aus allen verbundenen Tabellen. Mit anderen Worten: Spalten aus allen Tabellen werden nebeneinander angezeigt, d. h. die Daten werden horizontal gestapelt. UNION ist ein Mengenoperator, der für die Kombination der Ergebnisse von zwei oder mehr SELECT Anweisungen verwendet wird. Die Daten werden vertikal gestapelt. Eine der Voraussetzungen für die Verwendung von UNION ist, dass die Anzahl der Spalten in allen vereinigten SELECT Anweisungen gleich sein muss. Außerdem müssen alle ausgewählten Spalten vom gleichen Datentyp sein. 14. was ist der Unterschied zwischen UNION und UNION ALL? Beide haben gemeinsam, dass sie Mengenoperatoren sind. Außerdem werden beide Operatoren für denselben Zweck verwendet: die Zusammenführung von Daten aus zwei oder mehr SELECT Anweisungen. Auch die Anforderungen an die Anzahl der Spalten und deren Datentyp sind die gleichen. Der Unterschied besteht nun darin, dass UNION nur eindeutige Datensätze zurückgibt. Im Gegensatz dazu gibt UNION ALL alle Datensätze zurück, einschließlich der Duplikate. Normalerweise ist UNION ALL schneller, weil das Ergebnis nicht sortiert wird, um die Duplikate zu entfernen. Als Faustregel gilt, dass Sie standardmäßig UNION ALL verwenden sollten. Verwenden Sie UNION nur, wenn Sie eindeutige Ergebnisse benötigen oder absolut sicher sind, dass Ihre Abfrage keine doppelten Daten liefert. Mehr über die Syntax und die Verwendung von UNION erfahren Sie in diesem Artikel über die Unterschiede zwischen UNION und UNION ALL. 15 Was ist eine Unterabfrage in SQL? Eine Unterabfrage ist eine Abfrage, die innerhalb einer anderen SQL-Abfrage geschrieben wird. Die "andere" Abfrage wird als Hauptabfrage bezeichnet, während eine Unterabfrage manchmal auch als verschachtelte Abfrage bezeichnet wird. Unterabfragen können in den Anweisungen SELECT, INSERT, UPDATE, und DELETE verwendet werden. Sie können auch in Klauseln wie FROM oder WHERE verwendet werden, was die häufigste Verwendung ist. Hier ist ein Beispiel. Die Tabelle ist productsund speichert Informationen über Produktnamen, Mengen und Kategorien: idproduct_namequantityproduct_category 1Apple MacBook Air (2020) MGN63N/A Space Gray319Laptop 2Fairphone 4 128GB Green 5G208Mobile phone 3Apple iMac 24" (2021) 16GB/512GB Apple M1 with 8 core GPU Silver157Desktop 4HP 17-cp0971nd487Laptop 5Huawei P30 Pro - 128GB - Blue148Mobile phone 6Lenovo Legion T5 - AMD Ryzen 9 - 32 GB - 2TB HDD+SSD - Windows 10 Home PC514Desktop 7Toshiba Dynabook Satellite Pro E10-S-101 Notebook207Laptop 8Samsung Galaxy S23 5G - 256GB - Phantom Black56Mobile phone 9Intel Compleet PC | Intel Core i7-10700459Desktop Wir verwenden eine Unterabfrage und zeigen die Gesamtmenge nach Produktkategorie an, aber nur für die einzelnen Produkte, deren Menge über der durchschnittlichen Menge aller Produkte liegt. Hier ist die Lösung: SELECT product_category, SUM(quantity) AS product_quantity FROM products WHERE quantity > (SELECT AVG(quantity) FROM products) GROUP BY product_category; Die Abfrage wählt die Produktkategorie aus und summiert die Menge mit der Aggregatfunktion SUM(). Es gibt eine Bedingung in WHERE, die besagt, dass nur die einzelnen Produkte, deren Menge über dem Durchschnitt liegt, in die Summe aufgenommen werden. Wir verwenden die Unterabfrage und die Funktion AVG(), um diesen Durchschnitt zu ermitteln. Die Abfrage gibt zwei Zeilen zurück: product_categoryproduct_quantity Laptop806 Desktop973 Eine Kategorie fehlt, weil sie die Filterkriterien nicht erfüllt - Handys. Es gibt verschiedene Arten von Unterabfragen, z. B. skalare, mehrzeilige und korrelierte Abfragen. Mehr darüber erfahren Sie in unserem Artikel über Unterabfragetypen. 16 Schreiben Sie eine Abfrage, die Verkäufer und ihre monatlichen Umsatzdaten über ihrem persönlichen Umsatzdurchschnitt zurückgibt. Verwenden Sie eine korrelierte Unterabfrage. Eine korrelierte Unterabfrage ist ein Typ von Unterabfrage, der Werte aus der äußeren Abfrage verwendet. Sie wird für jede Zeile, die die äußere Abfrage zurückgibt, einmal überprüft, was die Leistung beeinträchtigen kann. In der Frage wird jedoch darauf bestanden, sie zu verwenden, also sehen wir uns die Daten an. Die erste Tabelle ist salesperson: idfirst_namelast_name 1NinaLee 2CarolinaGreen 3MickJohnson Die andere Tabelle ist sales: idsalesperson_idmonthly_salesperiod 111,200.472021_10 225,487.222021_10 33700.472021_10 4115,747.542021_11 5216,700.872021_11 5314,322.872021_11 619,745.552021_12 729,600.972021_12 836,749.582021_12 Ihre Aufgabe ist es, eine korrelierte Unterabfrage zu verwenden und den vollständigen Namen des Verkäufers, seinen monatlichen Umsatz und die Zeiträume, in denen sein Umsatz über seinem persönlichen Durchschnitt liegt, zurückzugeben. Hier ist die Lösung: SELECT first_name, last_name, monthly_sales, period FROM salesperson sp JOIN sales s ON sp.id = s.salesperson_id WHERE monthly_sales > (SELECT AVG(monthly_sales) FROM sales WHERE salesperson_id = sp.id); Die Abfrage wählt alle erforderlichen Spalten aus. Diese Daten stammen aus beiden Tabellen, also haben wir sie verbunden. Jetzt kommt der entscheidende Teil. Um die Daten zu filtern, verwenden wir die WHERE Klausel. Die Bedingung besagt, dass die Abfrage alle Daten zurückgeben soll, bei denen die monatlichen Umsätze höher sind als die durchschnittlichen Umsätze der einzelnen Vertriebsmitarbeiter. Wie berechnen wir diese individuellen Durchschnittsumsätze? Durch Verwendung der Funktion AVG() in der Unterabfrage, die wir in der Klausel WHERE schreiben. Hier ist die Ausgabe: first_namelast_namemonthly_salesperiod NinaLee15,747.542021_11 CarolinaGreen16,700.872021_11 MickJohnson14,322.872021_11 NinaLee9,745.552021_12 Weitere Beispiele finden Sie in diesem Artikel über korrelierte Unterabfragen. 17 Was sind Fensterfunktionen in SQL? Die SQL-Fensterfunktionen verdanken ihren Namen der Tatsache, dass sie auf ein Datenfenster angewendet werden. Dieses Fenster ist einfach eine Reihe von Zeilen, die mit der aktuellen Zeile zusammenhängen. Fensterfunktionen werden durch die Klausel OVER() eingeleitet. Eine weitere wichtige Klausel ist PARTITION BY, die Datenpartitionen innerhalb eines Fensterrahmens definiert. Wenn diese Klausel weggelassen wird, ist die Partition die gesamte Ergebnistabelle. Wenn PARTITION BY verwendet wird, können Sie eine oder mehrere Spalten definieren, nach denen die Daten partitioniert werden sollen. Sie können sie als GROUP BY für Fensterfunktionen betrachten. Eine weitere wichtige Klausel ist ORDER BY. Sie sortiert die Daten innerhalb des Fensters. Im Zusammenhang mit Fensterfunktionen gibt diese Klausel Anweisungen über die Reihenfolge, in der die Funktion ausgeführt werden soll. Weitere Informationen finden Sie in diesem Artikel über Fensterfunktionen. 18. was ist der Unterschied zwischen Fensterfunktionen und GROUP BY? Die einzige Gemeinsamkeit besteht darin, dass sowohl GROUP BY als auch die Fensterfunktionen mit den Aggregatfunktionen verwendet werden können - und dies auch sehr häufig tun - und dass sie beide mit einer Reihe von Zeilen arbeiten. Bei der Verwendung von GROUP BY wird die Ausgabe jedoch als Gruppe angezeigt, und Sie können die einzelnen Zeilen, die die Gruppe bilden, nicht sehen. Bei Fensterfunktionen gibt es solche Probleme nicht. Sie zeichnen sich unter anderem dadurch aus, dass sie die einzelnen Zeilen bei der Anzeige aggregierter Daten nicht einklappen. Das bedeutet, dass es möglich ist, aggregierte und nicht aggregierte Daten gleichzeitig anzuzeigen. Fensterfunktionen werden nicht nur für die Aggregation von Daten verwendet, wie Sie in der folgenden Frage sehen werden. Wenn Sie mehr über das aktuelle Thema wissen möchten, finden Sie hier einen Artikel, der Fensterfunktionen und GROUP BY erklärt. 19. welche Fensterfunktionen kennen Sie? SQL-Fensterfunktionen lassen sich im Allgemeinen in vier Kategorien einteilen: Ranking-Funktionen Verteilungsfunktionen Analytische Funktionen Aggregat-Funktionen Die Rangfolge-Funktionen sind: ROW_NUMBER() - Gibt eine eindeutige Nummer für jede Zeile innerhalb einer Partition zurück; gleichrangige Werte haben unterschiedliche Zeilennummern. RANK() - Ordnet Daten innerhalb einer Partition ein; gleichrangige Werte haben den gleichen Rang, und es gibt eine Lücke nach gleichrangigen Werten (z. B. 1, 2, 3, 3, 5). DENSE_RANK() - Ordnet Daten innerhalb einer Partition ein; gebundene Werte haben denselben Rang und es gibt keine Ranglücke (z. B. 1, 2, 3, 3, 4). Die Verteilungsfunktionen sind: PERCENT_RANK() - Gibt den relativen Rang innerhalb einer Partition zurück. CUME_DIST() - Gibt die kumulative Verteilung innerhalb einer Partition zurück. Die analytischen Funktionen sind: LEAD() - Ermöglicht den Zugriff auf Werte aus einer nachfolgenden Zeile in Bezug auf die aktuelle Zeile. LAG() - Ermöglicht den Zugriff auf die Werte einer vorherigen Zeile in Bezug auf die aktuelle Zeile. NTILE() - Unterteilt Zeilen innerhalb einer Partition in annähernd gleiche Gruppen. FIRST_VALUE() - Ermöglicht den Zugriff auf Werte aus der ersten Zeile innerhalb einer Partition. LAST_VALUE() - Ermöglicht den Zugriff auf Werte aus der letzten Zeile innerhalb einer Partition. NTH_VALUE() - Ermöglicht den Zugriff auf die n-te Zeile innerhalb einer Partition. Schließlich gibt es noch die Aggregatfunktionen: AVG() - Gibt einen Durchschnittswert für die Zeilen in einer Partition zurück. COUNT() - Gibt die Anzahl der Werte in den Zeilen einer Partition zurück. MAX() - Gibt den Maximalwert für die Zeilen in einer Partition zurück. MIN() - Gibt den Mindestwert für die Zeilen in einer Partition zurück. SUM() - Gibt den Summenwert der Zeilen in einer Partition zurück. In unserem Fensterfunktionen Cheat Sheet finden Sie weitere Informationen zu all diesen Funktionen. 20 Wie erstellt man eine Rangliste in SQL? Der einfachste Weg, Daten in SQL zu ordnen, ist die Verwendung einer der drei Funktionen des Ranglistenfensters: ROW_NUMBER() RANK() DENSE_RANK() Sie erhalten ein Dataset mit dem Namen album_sales mit den folgenden Daten: idartistalbumcopies_sold 1EaglesHotel California42,000,000 2Led ZeppelinLed Zeppelin IV37,000,000 3Shania TwainCome On Over40,000,000 4Fleetwood MacRumours40,000,000 5AC/DCBack in Black50,000,000 6Bee GeesSaturday Night Fever40,000,000 7Michael JacksonThriller70,000,000 8Pink FloydThe Dark Side of the Moon45,000,000 9Whitney HoustonThe Bodyguard45,000,000 10EaglesTheir Greatest Hits (1971-1975)44,000,000 Dies sind die Verkaufszahlen der zehn meistverkauften Alben der Geschichte. Wie Sie sehen können, sind die Alben nicht geordnet. Genau das werden wir hier tun: sie mit Hilfe von Fensterfunktionen von den besten zu den schlechtesten Verkäufen ordnen. Wenn Sie ROW_NUMBER() verwenden, sieht die Abfrage wie folgt aus: SELECT ROW_NUMBER() OVER (ORDER BY copies_sold DESC) AS rank, artist, album, copies_sold FROM album_sales; Die Syntax ist einfach. Zuerst wählen Sie die Fensterfunktion aus. Dann verwenden Sie die obligatorische OVER() -Klausel, die signalisiert, dass es sich um eine Fensterfunktion handelt. In ORDER BY sortieren Sie die Daten absteigend. Das bedeutet, dass die Zeilennummern entsprechend den verkauften Exemplaren von oben nach unten vergeben werden. Natürlich können Sie auch alle anderen benötigten Spalten auflisten und auf die Tabelle verweisen, um die gleiche Ausgabe zu erhalten: rankartistalbumcopies_sold 1Michael JacksonThriller70,000,000 2AC/DCBack in Black50,000,000 3Whitney HoustonThe Bodyguard45,000,000 4Pink FloydThe Dark Side of the Moon45,000,000 5EaglesTheir Greatest Hits (1971-1975)44,000,000 6EaglesHotel California42,000,000 7Shania TwainCome On Over40,000,000 8Fleetwood MacRumours40,000,000 9Bee GeesSaturday Night Fever40,000,000 10Led ZeppelinLed Zeppelin IV37,000,000 Wie Sie sehen können, sind die Alben von eins bis zehn geordnet. Zwei Alben haben 45 Millionen Exemplare verkauft. Sie werden jedoch nach zufälligen Kriterien unterschiedlich eingestuft (dritter und vierter Platz). Dasselbe geschieht mit drei Alben, die sich 40 Millionen Mal verkauft haben. Wenn Sie RANK() verwenden, ist die Syntax dieselbe, nur dass Sie eine andere Fensterfunktion verwenden: SELECT RANK() OVER (ORDER BY copies_sold DESC) AS rank, artist, album, copies_sold FROM album_sales; Die Ausgabe ist jedoch anders: rankartistalbumcopies_sold 1Michael JacksonThriller70,000,000 2AC/DCBack in Black50,000,000 3Whitney HoustonThe Bodyguard45,000,000 3Pink FloydThe Dark Side of the Moon45,000,000 5EaglesTheir Greatest Hits (1971-1975)44,000,000 6EaglesHotel California42,000,000 7Shania TwainCome On Over40,000,000 7Fleetwood MacRumours40,000,000 7Bee GeesSaturday Night Fever40,000,000 10Led ZeppelinLed Zeppelin IV37,000,000 Sie können sehen, dass die Alben mit Gleichstand an dritter Stelle stehen (zwei Mal). Das nächste Album ohne Gleichstand liegt auf dem fünften Platz. Dasselbe geschieht mit den Alben auf Platz sieben. Schauen wir uns an, was passiert, wenn wir DENSE_RANK() verwenden: SELECT DENSE_RANK() OVER (ORDER BY copies_sold DESC) AS rank, artist, album, copies_sold FROM album_sales; Hier ist das Ergebnis: rankartistalbumcopies_sold 1Michael JacksonThriller70,000,000 2AC/DCBack in Black50,000,000 3Whitney HoustonThe Bodyguard45,000,000 3Pink FloydThe Dark Side of the Moon45,000,000 4EaglesTheir Greatest Hits (1971-1975)44,000,000 5EaglesHotel California42,000,000 6Shania TwainCome On Over40,000,000 6Fleetwood MacRumours40,000,000 6Bee GeesSaturday Night Fever40,000,000 7Led ZeppelinLed Zeppelin IV37,000,000 Die ersten unentschiedenen Alben werden an dritter Stelle platziert, was dem vorherigen Ergebnis entspricht. Der Unterschied besteht jedoch darin, dass der nächste unentschiedene Rang der vierte ist - was bedeutet, dass die Rangliste nicht übersprungen wird. Die drei anderen gleichauf liegenden Alben liegen nun auf dem sechsten und nicht wie zuvor auf dem siebten Platz. Auch der höchste Rang ist der siebte und nicht der zehnte. Wie Sie sehen können, liefert jede Methode unterschiedliche Ergebnisse. Sie sollten die Methode verwenden, die am besten zu Ihren Daten und den gewünschten Ergebnissen passt. Lesen Sie den Artikel über die Rangfolge von Zeilen in SQL, um mehr zu erfahren. 21. was ist der Unterschied zwischen RANK() und DENSE_RANK()? Wir haben den Unterschied bereits in der vorherigen Frage angesprochen. Sie haben ihn dort in einem praktischen Beispiel gesehen, und jetzt lassen Sie uns ihn formulieren, um diese Frage zu beantworten. RANK() ordnet Zeilen mit gleichen Werten den gleichen Rang zu. Wenn es zur nächsten nicht gebundenen Zeile kommt, überspringt es den Rang um die Anzahl der gebundenen Ränge. DENSE_RANK() gibt auch den gebundenen Werten den gleichen Rang. Der Rang wird jedoch nicht übersprungen, wenn er die nächste nicht gebundene Zeile erreicht. Mit anderen Worten: DENSE_RANK() ordnet die Daten sequentiell. Weitere Einzelheiten werden in diesem Artikel über die Unterschiede zwischen RANK() und DENSE_RANK() erläutert. 22. die obersten n Zeilen in SQL mit einer Fensterfunktion und einem CTE finden. Dies ist eine häufig gestellte Frage, die auf verschiedene Weise gelöst werden kann. Wir werden die Window-Funktion in einer CTE verwenden, um das gewünschte Ergebnis zu erhalten. Die verfügbaren Daten sind in der salary Tabelle: idfirst_namelast_namesalarydepartment 1TimThompson10,524.74Sales 2MartinaHrabal7,895.14Accounting 3SusanTruman15,478.69Sales 4CiroConte8,794.41Accounting 5JorgeDe Lucia7,489.15Sales 6CarmenLopez10,479.15Accounting 7CatherineMolnar8,794.89Sales 8RichardBuchanan12,487.69Accounting 9MarkWong9,784.19Sales 10SilviaKarelias9,748.64Accounting Die Aufgabe besteht darin, die drei höchstbezahlten Mitarbeiter in jeder Abteilung mit ihrem Gehalt und ihrer Abteilung zu ermitteln. Die Vorgehensweise ist wie folgt: WITH ranking AS ( SELECT first_name, last_name, salary, department, DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS salary_rank FROM salary ) SELECT * FROM ranking WHERE salary_rank <= 3 ORDER BY department, salary_rank; Der erste Teil des Codes ist ein Common Table Expression, kurz CTE. Er wird mit dem Schlüsselwort WITH eingeleitet. Der CTE trägt den Namen ranking. Nach dem Schlüsselwort AS schreiben wir die CTE-Definition als SELECT -Anweisung in Klammern. Nach der Auswahl aller erforderlichen Spalten kommt ranking, wir verwenden die DENSE_RANK() Funktion. Sie können auch jede andere Funktion des Ranking-Fensters verwenden, wenn Sie möchten. Die Syntax ist bekannt. Um die Rangfolge nach Abteilung zu erhalten, müssen wir die Daten nach dieser Spalte partitionieren. Außerdem wollen wir die Gehälter von hoch nach niedrig einstufen. Mit anderen Worten: Die Daten in der Partition müssen nach Gehalt in absteigender Reihenfolge geordnet werden. Die zweite Anweisung SELECT (d. h. die äußere Abfrage) wählt alle Spalten aus dem CTE aus und setzt die Bedingung in der Klausel WHERE, um nur die drei höchsten Gehälter nach Abteilung zu filtern. Schließlich wird die Ausgabe nach Abteilung und Gehaltsrang sortiert. Hier ist das Ergebnis: first_namelast_namesalarydepartmentsalary_rank RichardBuchanan12,487.69Accounting1 CarmenLopez10,479.15Accounting2 SilviaKarelias9,748.64Accounting3 SusanTruman15,478.69Sales1 TimThompson10,524.74Sales2 MarkWong9,784.19Sales3 23. die Differenz zwischen zwei Zeilen (Delta) berechnen mit Fensterfunktionen Dieses Problem wird am elegantesten mit der Funktion LAG() window gelöst. Denken Sie daran, dass es sich um eine Funktion handelt, die auf den Wert der vorherigen Zeile zugreift. Die Beispieldaten finden Sie in der Tabelle revenue: idactual_revenueperiod 18,748,441.222022_07 210,487,444.592022_08 37,481,457.152022_09 47,497,441.892022_10 58,697,415.362022_11 612,497,441.562022_12 Sie müssen den tatsächlichen Umsatz, den Zeitraum und die monatliche Differenz (Delta) zwischen dem tatsächlichen Umsatz und dem des Vormonats anzeigen. So wird es gemacht. SELECT actual_revenue, actual_revenue - LAG(actual_revenue) OVER (ORDER BY period ASC) AS monthly_revenue_change, period FROM revenue ORDER BY period; Ein Delta wird berechnet, indem der Vormonat vom aktuellen Monat abgezogen wird. Genau das macht diese Abfrage! Um den Umsatz des Vormonats zu erhalten, ist die Funktion LAG() sehr nützlich. Die Spalte actual_revenue ist das Argument der Funktion, da wir auf die Umsatzdaten der vorherigen Zeile zugreifen wollen. Wie bei jeder Fensterfunktion gibt es eine OVER() -Klausel. Darin haben wir die Daten nach Zeitraum aufsteigend sortiert, weil es logisch ist, das Delta chronologisch zu berechnen. Dies ist die Ausgabe der Abfrage: actual_revenuemonthly_revenue_changeperiod 8,748,441.22NULL2022_07 10,487,444.591,739,003.372022_08 7,481,457.15-3,005,987.442022_09 7,497,441.8915,984.742022_10 8,697,415.361,199,973.472022_11 12,497,441.563,800,026.202022_12 Die erste zeigt die Umsatzänderung als NULL an. Dies ist zu erwarten, da es keinen früheren Monat gibt, von dem man abziehen könnte. Im Jahr 2022_08 gab es eine Umsatzsteigerung von 1.739.003,37 = Umsatz des aktuellen Monats - Umsatz des Vormonats = 10.487.444,59 - 8.748.441,22. Ähnliche Beispiele finden Sie in dem Artikel über die Berechnung der Differenz zwischen zwei Zeilen in SQL. 24. Fensterfunktionen verwenden, um eine laufende Summe zu berechnen Eine laufende oder kumulative Summe ist die Summe einer Zahlenfolge. Die laufende Summe wird jedes Mal aktualisiert, wenn ein neuer Wert zu der Folge hinzugefügt wird. Denken Sie an die monatlichen Einnahmen: Die Gesamteinnahmen des aktuellen Monats umfassen die Summe der Einnahmen des aktuellen Monats und aller Vormonate. Die Fensterfunktion, die sich perfekt für die Berechnung einer laufenden Summe (kumulative Summe) eignet, ist SUM(). Zeigen wir den Ansatz anhand der gleichen Daten wie in der vorherigen Frage. Ziel ist es, die kumulierten Einnahmen für alle verfügbaren Monate im Jahr 2022 zu berechnen. Hier ist die Lösung: SELECT actual_revenue, SUM(actual_revenue) OVER (ORDER BY period ASC) AS cumulative_revenue, period FROM revenue; Die kumulative Summe ist die Summe der Einnahmen des aktuellen Monats und die Summe der Einnahmen aller Vormonate. Die Funktion SUM() window wendet diese Logik an. Das Argument der Funktion ist der aktuelle Umsatz, denn das ist es, was wir summieren. Damit die Funktion alle vorherigen Einnahmen und die aktuellen Einnahmen summiert, sortieren Sie die Daten aufsteigend nach Zeitraum. Auch hier ist es logisch, eine kumulierte Summe vom frühesten bis zum letzten Monat zu berechnen. Dies ist das Ergebnis des Codes: actual_revenuecumulative_revenueperiod 8,748,441.228,748,441.222022_07 10,487,444.5919,235,885.812022_08 7,481,457.1526,717,342.962022_09 7,497,441.8934,214,784.852022_10 8,697,415.3642,912,200.212022_11 12,497,441.5655,409,641.772022_12 Der kumulierte Umsatz in der ersten Zeile ist gleich dem tatsächlichen Umsatz. Für die zweite Zeile beträgt die kumulierte Summe 19.235.885,81 = 8.748.441,22 + 10.487.444,59. Im September beträgt die kumulierte Summe 26.717.342,96 = 8.748.441,22 + 10.487.444,59 + 7.481.457,15. Die gleiche Logik gilt auch für den Rest der Tabelle. Hier erfahren Sie mehr über die laufende Summe und wie man sie berechnet. 25. einen gleitenden Durchschnitt finden mit Fensterfunktionen Ein gleitender Durchschnitt wird bei der Analyse einer Reihe verwendet. Sie finden ihn auch unter anderen Bezeichnungen wie gleitendes Mittel, gleitender Durchschnitt oder laufender Durchschnitt. Es handelt sich dabei um einen Durchschnitt aus dem aktuellen Wert und der festgelegten Anzahl der vorangegangenen Werte. Ein gleitender 7-Tage-Durchschnitt ist zum Beispiel der Durchschnitt des aktuellen Tages und der sechs vorangegangenen Tage. Um Ihnen zu zeigen, wie Sie ihn berechnen können, verwenden wir die eur_usd_rate Tabelle: idexchange_ratedate 11.06662022-12-30 21.06832023-01-02 31.05452023-01-03 41.05992023-01-04 51.06012023-01-05 61.05002023-01-06 61.06962023-01-09 71.07232023-01-10 81.07472023-01-11 91.07722023-01-12 101.08142023-01-13 Wir berechnen den gleitenden 3-Tage-Durchschnitt auf folgende Weise: SELECT exchange_rate, AVG(exchange_rate) OVER (ORDER BY date ASC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS eur_usd_moving_average, date FROM eur_usd_rate; Wir verwenden die Fensterfunktion AVG() für die Spalte exchange_rate. In der Klausel OVER() werden die Daten nach Datum in aufsteigender Reihenfolge sortiert. Jetzt kommt der wichtige Teil! Erinnern Sie sich, dass wir einen gleitenden 3-Tage-Durchschnitt benötigen, der die aktuelle und die beiden vorherigen Zeilen umfasst. Wir geben das in der BETWEEN Klausel an: Wir sagen der Funktion, dass sie die zwei vorangegangenen Zeilen und die aktuelle Zeile einbeziehen soll. Werfen wir einen Blick auf das Ergebnis: exchange_rateeur_usd_moving_averagedate 1.06661.06662022-12-30 1.06831.06752023-01-02 1.05451.06312023-01-03 1.05991.06092023-01-04 1.06011.05822023-01-05 1.05001.05672023-01-06 1.06961.05992023-01-09 1.07231.06402023-01-10 1.07471.07222023-01-11 1.07721.07472023-01-12 1.08141.07782023-01-13 Der gleitende Durchschnitt des ersten Datums ist derselbe wie der Wechselkurs, denn: 1.0666/1 = 1.0666. Für 2023-01-02 wird er wie folgt berechnet: (1,0666 + 1,0683)/2 = 1,0675. Im Jahr 2023-01-03 haben wir schließlich drei Daten: (1,0666 + 1,0683 + 1,0545)/3 = 1,0631. Diese Logik gilt auch für alle anderen Datumsangaben. Weitere Beispiele finden Sie in diesem Artikel über die Berechnung von gleitenden Durchschnitten in SQL. 26. was ist der Unterschied zwischen ROWS und RANGE? Sowohl ROWS als auch RANGE sind Klauseln, die zur Definition eines Fensterrahmens verwendet werden. Sie begrenzen den in einer Fensterfunktion verwendeten Datenbereich innerhalb einer Partition. Die Klausel ROWS begrenzt die Zeilen. Sie wird verwendet, um eine feste Anzahl von Zeilen vor und nach der aktuellen Zeile anzugeben. Der Wert der Zeilen wird dabei nicht berücksichtigt. Die RANGE Klausel schränkt den Datenbereich logisch ein. Mit anderen Worten, sie schränkt die Daten ein, indem sie die Werte der vorangehenden und nachfolgenden Zeilen im Verhältnis zur aktuellen Zeile betrachtet. Die Anzahl der Zeilen bleibt dabei unberücksichtigt. Wie verwendet man sie in der Praxis? Lesen Sie unseren Artikel über ROWS und RANGE für weitere Einzelheiten. 27 Verwenden Sie eine rekursive Abfrage, um alle Mitarbeiter unter einem bestimmten Manager zu finden. Eine rekursive Abfrage ist eine spezielle Art von CTE, die auf sich selbst verweist, bis sie das Ende der Rekursion erreicht. Sie ist ideal für die Abfrage von Graphdaten oder hierarchischen Strukturen. Ein Beispiel für Letzteres ist die Organisationsstruktur des Unternehmens, die in der company_organization Tabelle: employee_idfirst_namelast_namemanager_id 5529JackSimmons5125 5238MariaPopovich5329 5329DanJacobsson5125 5009SimoneGudbois5329 5125AlbertKochNULL 5500JackieCarlin5529 5118SteveNicks5952 5012BonniePresley5952 5952HarryRaitt5529 5444SeanElsam5329 Diese Tabelle zeigt alle Mitarbeiter und die ID ihres direkten Vorgesetzten. Die Aufgabe besteht hier darin, die Rekursion zu nutzen und alle direkten und indirekten Untergebenen von Jack Simmons zurückzugeben. Außerdem fügen wir eine Spalte hinzu, die zur Unterscheidung der verschiedenen Organisationsebenen verwendet werden kann. Hier ist der Code: WITH RECURSIVE subordinates AS ( SELECT employee_id, first_name, last_name, manager_id, 0 AS level FROM company_organization WHERE employee_id= 5529 UNION ALL SELECT co.employee_id, co.first_name, co.last_name, co.manager_id, level + 1 FROM company_organization co JOIN subordinates s ON co.manager_id = s.employee_id ) SELECT s.employee_id, s.first_name AS employee_first_name, s.last_name AS employee_last_name, co.employee_id AS direct_manager_id, co.first_name AS direct_manager_first_name, co.last_name AS direct_manager_last_name, s.level FROM subordinates s JOIN company_organization co ON s.manager_id = co.employee_id ORDER BY level; Wir starten die Rekursion mit WITH RECURSIVE. (Wenn Sie in MS SQL Server arbeiten, verwenden Sie nur WITH.) Die erste SELECT in einer CTE wird Ankermitglied genannt. Darin verweisen wir auf das Dataset und wählen alle erforderlichen Spalten aus. Außerdem erstellen wir eine neue Spalte mit dem Wert Null und filtern die Daten in der WHERE Klausel. Warum wird genau diese Bedingung in WHERE verwendet? Weil die Mitarbeiter-ID von Jack Simmons 5529 ist und wir ihn und seine Untergebenen anzeigen wollen. Dann folgt die UNION ALL, die die Ergebnisse der Ankerabfrage und der rekursiven Abfrage kombiniert, d. h. die zweite SELECT Anweisung. Wir möchten, dass die Rekursion bis hinunter in die Organisationsstruktur geht. In der rekursiven Abfrage verknüpfen wir die CTE mit der company_organization Tabelle. Wir listen wiederum alle erforderlichen Spalten der letztgenannten Tabelle auf. Außerdem wollen wir bei jeder Rekursion eine Organisationsebene hinzufügen. Schließlich kommen wir zu der Abfrage, die die CTE verwendet. Diese Abfrage dient dazu, Daten sowohl aus der CTE als auch aus der company_organization Tabelle. Wir verwenden die CTE, um die Mitarbeiterdaten anzuzeigen. Die andere Tabelle wird verwendet, um die Daten des direkten Vorgesetzten anzuzeigen. Wenn Sie den Code ausführen, erhalten Sie dieses Ergebnis: employee_idemployee_first_nameemployee_last_namedirect_manager_iddirect_manager_first_namedirect_manager_last_namelevel 5529JackSimmons5125AlbertKoch0 5952HarryRaitt5529JackSimmons1 5500JackieCarlin5529JackSimmons1 5012BonniePresley5952HarryRaitt2 5118SteveNicks5952HarryRaitt2 Die obige Tabelle zeigt, dass der direkte Vorgesetzte von Jack Simmons Albert Koch ist. Direkt unter Simmons stehen Harry Raitt und Jackie Carlin. Die indirekten Untergebenen sind Bonnie Presley und Steve Nicks. Ihr direkter Vorgesetzter ist Harry Raitt. Einige andere Varianten dieser Aufgabe finden Sie im Artikel über rekursive CTEs. Mehr über Fensterfunktionen erfahren Sie in diesem Artikel über SQL-Fensterfunktionen, der sich mit Fragen zu Vorstellungsgesprächen befasst. Sind Sie bereit, die SQL-Interviewfragen zu meistern? Es war nicht einfach, diesen Leitfaden zu schreiben. Aber es hat sich gelohnt, wenn wir daran denken, wie Sie Ihr fortgeschrittenes SQL-Vorstellungsgespräch einfacher gestalten können. Natürlich sind dies nicht alle Fragen, die Ihnen im Vorstellungsgespräch gestellt werden könnten. Wir glauben jedoch, dass diese Auswahl Ihnen eine solide Grundlage für die wichtigsten fortgeschrittenen SQL-Konzepte bietet. Dieser Leitfaden ist außerdem kurz genug, damit Sie ihn vor dem Vorstellungsgespräch schnell durchgehen und Ihr Gedächtnis auffrischen können. Wenn Sie weitere Auffrischungen zu fortgeschrittenen SQL-Themen benötigen, besuchen Sie unseren Fensterfunktionen Kurs oder Fortgeschrittenes SQL Kurs. Tags: Jobs und Karriere SQL-Interviewfragen