Wie entfernen von Bedingungen aus der WHERE-Klausel, wenn Parameter NULL ist
Bin ich durch ein 2-Parameter eine PL/pgSQL-Funktion. Hier ist die Abfrage:
SELECT *
FROM table
WHERE col1 = param1
AND col2 = param2
Beide Parameter kann NULL sein, in welchem Fall der entsprechende Ausdruck sollte entfernt werden aus der WHERE
- Klausel.
Wie kann ich das tun? Mit IF
Bedingungen?
- Ist die Funktion geschrieben in
plpgsql
(im Gegensatz zum einfachen SQL oder eine andere austauschbare Sprachen)? - seine schlichte plppgsql
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vielleicht ist das der trick:
Dies ist nicht die Beseitigung der UND-Zustand, aber sollte das unwichtig im Falle von param2 den Wert null. So nicht klar beantworten Ihre Frage doch herum... 😉
WHERE (param1 is null or col1 = param1) AND (param2 is null or col2 = param2)
. Natürlich wäre dies alles zurück, wenn beide eine null. Vielleicht denken Sie über gültige default-Werte zu diesem Zeitpunkt?Einem einfachen
(param1 IS NULL OR col1 = param1)
übernimmt dies, wie schon bereits beantwortet.Zu tatsächlich entfernen beliebige oder alle NULL-Bedingungen, die Sie benötigen, dynamische SQL -. Sie können bauen Sie Ihre Anweisung in den client-bedingt oder erstellen Sie eine plpgsql (oder einer anderen prozeduralen Sprache) - Funktion zu übernehmen. Dieser Ansatz führen kann, superior-Abfrage Pläne beim Umgang mit komplexen Abfragen.
PL/pgSQL - Funktion
Kniffligen Teile sind:
Drei Beispiele für den Aufruf:
SQL Fiddle.
Müssen Sie haben ein grundlegendes Verständnis von plpgsql für diese. Sie finden viele Beispiele mit reichlich Erklärung in der plpgsql - tag.
Die einfachste (wenn auch wahrscheinlich nicht die effizienteste) Weg ist, behandeln die null innerhalb des SQL-Statements selbst, z.B.:
Diese übergibt die Klausel für alle Zeilen, wenn der parameter null ist.
Oder mit diesem trick:
Wenn
param2
istNULL
ist die Bedingung äquivalent zucol2 = col2
, die immer true sein solangecol2
nicht selbst enthaltenNULL
Werte.Einen quick-test unter Verwendung von hart codierten Werten und nicht als eine Funktion der parameter gab mir den gleichen Abfrageplan für beide Ansätze - die
OR
undCOALESCE
Teile sind scheinbar optimierten Weg, bevor die Planung der Abfrage, so ist es, als ob die zweiteAND
waren tatsächlich bedingt entfernt.NULL
oder string stattparam2
, und bekam die identische Abfrage-Pläne für beide Strategien. Da es konstant für alle Zeilen, die erste wird entwederTRUE OR ...
oderFALSE OR ...
, die optimiert werden können, entfernt, und der zweite wirdCOALESCE(NULL, col2)
oderCOALESCE('known value', col2)
ersetzt werden können durchcol2
und'known value'
vor der Planung der Abfrage.col2 = col2
wird nicht immer wahr sein. Wenncol2
könnte die null-Werte enthalten, in diesem Zustand konnteunknown
, so dass diese Methode nicht nur nicht auf dem index, aber es könnte auch zurückgeben, falsche Ergebnissecol2
; ich werde eine Anmerkung hinzufügen, dass.