A simple (param1 IS NULL OR col1 = param1)
takes care of this, as has been answered already.
To actually remove any or all NULL conditions, you need dynamic SQL. You can build your statement in the client conditionally or you can create a plpgsql (or any other procedural language) function to take care of it. This approach may result in superior query plans when dealing with complex queries.
The tricky parts are:
- to deal with NULL values and empty strings properly in string concatenation
- to deal with variable data types while avoiding possible SQL injection
CREATE OR REPLACE FUNCTION f_conditional_where(_param1 int = NULL
, _param2 text = NULL
, _param3 date = NULL)
RETURNS SETOF tbl AS
$func$
DECLARE
_where text :=
concat_ws(' AND '
, CASE WHEN _param1 IS NOT NULL THEN 'col1 = $1' END
, CASE WHEN _param2 IS NOT NULL THEN 'col2 = $2' END
, CASE WHEN _param3 IS NOT NULL THEN 'col3 = $3' END);
_sql text := 'SELECT * FROM tbl';
BEGIN
IF _where <> '' THEN
_sql := _sql || ' WHERE ' || _where;
END IF;
-- debug output
RAISE NOTICE '
_sql: |%|
_where: |%|', _sql, _where;
-- execute
RETURN QUERY EXECUTE _sql
USING $1, $2, $3;
END
$func$ LANGUAGE plpgsql;
Three examples for function call:
SELECT * FROM f_conditional_where();
SELECT * FROM f_conditional_where(1, 'foo');
SELECT * FROM f_conditional_where(_param3 := '2012-01-01', _param2 := 'foo');
SQL Fiddle.
You need to have a basic understanding of plpgsql for this. You'll find plenty of examples with ample explanation in the plpgsql tag.