我正在尝试在PostgreSQL 9.3.5中实现一个日期作为参数的函数 它应涵盖以下所有条件并相应地返回结果。
select * from tablename
where sid is not null and dob >= '11-14-2014' order by dob;
-- Only Start Date
select * from tablename
where sid is not null and dob <= '11-21-2014' order by dob;
-- Only End Date
select * from tablename
where sid is not null and dob between '11-10-2014' and '11-21-2014' order by dob;
-- Both Start and End Dates are Given
select * from tablename
where sid is not null and dob is null;
-- Both Start and End Dates are Null
但我上面的SQL Fiddle没有按预期工作。
我希望有一个通用实现,这样如果明天我在标准搜索中有更多new Date Fields
,那么我可以将它们添加到where condition
中,但不能添加到IF
的每一行中1}}陈述。
答案 0 :(得分:1)
这可以 更简单 :
您可以简化@ Clodoaldo目前接受的答案:
SELECT *
FROM sampletest
WHERE eid IS NOT NULL
AND (_sd IS NULL AND _ed IS NULL OR
_sd IS NULL AND dob <= _ed OR
_ed IS NULL AND dob >= _sd OR
dob BETWEEN _sd AND _ed);
dob >= _sd
后,无需另外检查_sd is not null
无论如何,表达式只能评估为TRUE
非空_sd
。但这些都不是必要的:
CREATE OR REPLACE FUNCTION test_dob_dates(_sd date, _ed date)
RETURNS SETOF sampletest AS
$func$
SELECT *
FROM sampletest
WHERE eid IS NOT NULL
AND dob BETWEEN COALESCE(_sd, -infinity) AND COALESCE(_ed, infinity)
$func$ LANGUAGE sql STABLE;
timestamp
和date
类型提供special values -infinity
and infinity
。您只需使用COALESCE
默认使用这些值。SQL Fiddle(第9.3页)。
除此之外:我建议使用标准ISO日期 '2014-11-10'
,而不是 ,这可能是不明确的,并打破了不同的区域设置设置。 The manual advises as much. '11-10-2014'
答案 1 :(得分:0)
您必须将函数定义为返回set of
sampletest,然后根据传递的参数返回return different query restults。
CREATE FUNCTION
test_dob_dates(_sd date, _ed date)
RETURNS
SETOF sampletest
AS
$BODY$
BEGIN
IF _sd IS NOT NULL AND _ed IS NOT NULL THEN
RETURN QUERY SELECT * FROM sampletest WHERE dob BETWEEN _sd AND _ed;
ELSIF _sd IS NULL AND _ed IS NULL THEN
RETURN QUERY SELECT * FROM sampletest WHERE dob IS NULL;
ELSEIF _ed IS NOT NULL THEN
RETURN QUERY SELECT * FROM sampletest WHERE dob <= _ed;
ELSE
RETURN QUERY SELECT * FROM sampletest WHERE dob >= _sd;
END IF;
END;
$BODY$
LANGUAGE
'plpgsql' VOLATILE;
eid IS NOT NULL
子句似乎是多余的,因为您已将eid
定义为PRIMARY KEY,这意味着它永远不会为NULL。
答案 2 :(得分:0)
create function test_dob_dates(_sd date, _ed date)
returns setof sampletest as $body$
select *
from sampletest
where
eid is not null
and (
(_sd is null and _ed is null)
or (_sd is not null and _ed is null and dob >= _sd)
or (_sd is null and _ed is not null and dob <= _ed)
or dob between _sd and _ed
);
$body$ language sql stable;