Melvin Cowznofski: Geburtstage der letzten und kommenden 3 Tage

Beitrag lesen

Hallo dedlfix!

Nach AS steht ein Aliasname, der zum Beispiel als "Feldname" in der Ergebnismenge auftaucht. Ansonsten steht da nämlich exakt das was im SELECT steht: ein Feldname oder der komplette Ausdruck.

Wofür das AS steht, war mir schon klar. Den Block davor habe ich nicht verstanden.

FROM -> WHERE -> GROUP BY -> SELECT -> HAVING -> ORDER BY -> LIMIT

_Das_ ist sehr interessant! Vielen Dank für diese Info!

Der Aliasname wird nach der Berechnung vergeben und im WHERE ist er noch gar nicht vorhanden.

Das verstehe ich jetzt, wenn ich mir die Abarbeitungsfolge, die Du geschrieben hast, ansehe.

Es gibt eine Reihenfolge, in der die Klauseln ausgewertet werden. Aliasnamen sind immer erst nach dem Abarbeiten der jeweiligen Klausel für die anderen Klauseln verfügbar.

Also, wenn ich mir die Abarbeitungsfolge ansehe, erst nach dem SELECT, sprich im HAVING, und im ORDER BY.

Aliasnamen im SELECT können im ORDER BY verwendet werden. Im HAVING auch

Na dann verstehe ich das ja richtig.

aber das sollte man nicht als WHERE-Ersatz missbrauchen, weil das unnötig Ressourcen verbraucht (wenn es der Optimizer nicht wegoptimiert).

Das verstehe ich nicht so ganz. Was wäre denn ein _simples_ Beispiel für so einen unötigen WHERE-Ersatz? Anders gefragt: Kann man den Unterschied/Verwendungszweck bei WHERE und HAVING irgendwie verständlich erklären?

Das heißt, im WHERE kann man auf Aliasnamen (und Berechnungsergebnisse) für Tabellen zugreifen und nicht auf die im SELECT.

Also das ist mir jetzt _völlig_ unverständlich! Was meinst Du mit "Aliasnamen (und Berechnungsergebnisse) für Tabellen"?

SELECT preis, (preis * 2) AS doppelter_preis FROM katalog

Hier ist "doppelter_preis" ein Aliasname einer virtuellen Spalte. Also einer Spalte, die es in der Datenbank eigentlich gar nicht real gibt. Gefüllt mit berechneten Werten. Der Aliasnahme entstammt dem SELECT, kann also, wie wir vorher festgestellt haben, nur im HAVING und im ORDER BY verwendet werden. Und was wäre im Gegensatz dazu jetzt ein "Aliasnamen (und Berechnungsergebnis) für Tabellen", auf den ich laut Deinem Satz auch im WHERE zugreifen kann?

Mal angenommen, du hast keine Berechnung sondern einen einfachen Vergleich im WHERE, dann kann unter Umständen ein Index zum schnelleren Finden der Datensätze verwendet werden. Sortierst du erst im HAVING die ungewünschten Datensätze weg, dann arbeitest du bereits mit den Daten der Ergebnismenge und nicht mehr mit den Daten aus der Tabelle. Dann hat das SELECT vielleicht viele Berechnungen (für die anderen Felder) umsonst angestellt, deren Datensätze das WHERE gar nicht erst durchgelassen hätte.

Ich bilde mir zwar ein, das zumindest teilweise zu verstehen, wenn ich dabei auf die von Dir gepostete Avarbeitungsfolge schaue, aber so ganz klar ist mir die Sache nicht. Kannst Du das evt. an Hand eines ganz trivialen Beispiels verständlich machen?

Es gibt eine deutlich einfachere, wenn man den 29. Februar außen vor lässt. DAYOFYEAR() spart eine ganze Menge Funktionsaufrufe.

_Das_ war ursprünglich das Erste, woran ich gedacht habe und meine ersten Lösungsversuche gingen auch in diese Richtung. Ich fand das allerdings unbrauchbar, weil die Tage nach dem 28. Februar in den Schlatjahren nicht der selbe "day of year" sind und somit wurden zB. die Schaltjahr-Geburtstage bei den Geburtstagen vor 3 Tagen nicht mitangezeigt. Nein, das DAYOFYEAR() bringt in diesem Fall nichts. Aber meine finale Lösung funktioniert eh wunderbar.

Die relevante Stelle sieht gekürzt so aus:
... + IF(x > y, 1, 0)
1 und 0 sind Parameter der IF-Funktion. Das IF() liefert abhängig vom Vergleichsergebnis eine 1 oder 0 und die wird zum vorhergehenden Teilausdruck addiert.

Danke, jetzt ist es klar!

Mit lieben Grüßen

Melvin Cowznofski

--

Melvin Cowznofski
What – me worry?