filter_plugin
eines Fremdanbieters verwendet reguläre Ausdrücke, um Filter
als Case
umzuschreibenDie Filter
-Klausel kann generell durch einen Case
-Ausdruck in der Aggregatfunktion umgesetzt werden. Dazu wird die Filterbedingung in die When
-Klausel, der zu aggregierende Wert in die Then
-Klausel übernommen. Da Aggregatfunktionen Null
generell nicht berücksichtigen1, genügt die implizite Else Null
-Klausel, um nicht passende Zeilen zu ignorieren. Die folgenden Ausdrücke sind daher gleichwertig.
SUM(<Ausdruck>) FILTER(WHERE <Bedingung>)
SUM(CASE WHEN <Bedingung> THEN <Ausdruck> END)
Lediglich Count(*)
ist noch als Spezialfall zu nennen, da man „*“ nicht direkt in die Then
-Klausel schreiben kann. Es genügt jedoch, den Stern durch einen Nicht-Null
-Konstante zu ersetzen. Damit ist sichergestellt, dass jede passende Zeile gezählt wird. Für die nicht passenden Zeilen liefert der implizite Else Null
-Zweig Null
, was auch von Count
ignoriert wird.
COUNT(*) FILTER (WHERE <Bedingung>)
COUNT(CASE WHEN <Bedingung> THEN 1 END)
Falls ein set quantifier (Distinct
oder All
) verwendet wird, muss dieser in der Aggregatfunktion vor Case
erhalten bleiben.
Ich biete SQL Schulungen, Optimierung und Beratung an. Auch der Kauf meines Buches „SQL Performance Explained“ (ab €9,95) unterstützt meine Arbeit an dieser Webseite.
Die PostgreSQL-Datenbank unterstützt die Verwendung von Unterabfragen in der Filter
-Klausel (z. B. mittels Exists
).
Da die oben beschriebene Standard-Alternative mit einem Case
-Ausdruck weitestgehend unterstützt wird, rate ich von der Verwendung dieser proprietären Alternativen generell ab.
Countif
(Google BigQuery)Google BigQuery bietet die Aggregatfunktion Countif
an, die vor allem aus Microsoft Excel bekannt ist.
COUNTIF(<Bedingung>) [OVER(…)]
Dasselbe Ergebnis kann man mit der Case
-Alternative erreichen, die dann ein allen gängigen Datenbanken funktioniert:
COUNT(CASE WHEN <Bedingung> THEN 1 END) [OVER(…)]
Markus verwandelt veraltetes SQL-92-Wissen in solides und zeitgemäßes SQL-Know-how
SQL:2016-2: §10.9, Syntax Rule 8.
Beim der Emulation mit Case
werden lediglich Window-Funktionen ausgeschlossen: SQL:2016-2: §10.9, Syntax Rule 7a.
SQL:2016-2: §10.9, General Rule 7a (für gewöhnliche Aggregate), 8a (für binäre Set-Operationen), 10d (für inverse Set-Operationen). Siehe auch SQL:2016-2: §4.16.4.
Ausnahme: Array_agg
(SQL:2016-2: §10.9, General Rule 12gii, explizit in Bemerkung 510) – Bei dem Array-Konstruktor mittels Abfrage kann man Null
-Werte auch ohne Filter
-Klausel entfernen.