在psql
shell中,我总是在编写这样的查询:
SELECT * FROM transactions WHERE date >= '11-01-2016' AND date < '12-01-2016'
能够写出这样的东西会更好:
SELECT * FROM transactions WHERE IN_MONTH(11)
并让IN_MONTH
解析为适当的条件。在这种情况下,Postgres的“用户定义函数”概念是否适用? docs
SQL函数执行任意SQL语句列表,返回列表中最后一个查询的结果。
让我觉得他们没有,我需要别的东西。
答案 0 :(得分:1)
您可以创建SQL函数,如果未标记为STRICT
,则有时可以内联。例如:
CREATE FUNCTION in_month(date, integer)
RETURNS boolean
LANGUAGE SQL AS $$
SELECT extract('month' FROM $1) = $2
$$;
除非您在extract('month' from columnname)
上有表达式索引,否则这通常不是可索引的。如果您只对某个特定日期中的一个月感兴趣,而不是在任何一年中该月内的任何日期感兴趣,则传递日期而不是整数月份数并使用between
更有效,例如
CREATE FUNCTION in_month(date, date)
RETURNS boolean
LANGUAGE SQL AS $$
SELECT $1
BETWEEN date_trunc('month', $2)
AND (date_trunc('month', $2) + INTERVAL '1' MONTH) - INTERVAL '1' DAY;
$$;
因为这允许在日期列上使用b树索引来扫描范围。编写date_trunc('month', mycol) = date_trunc('month', 'thedate')
是更简单,但它无法在mycol
上使用索引,它需要date_trunc('month', mycol)
上的单独索引。由于额外的索引会降低性能,因此如果您可以改写查询,请不要添加它们。
Postgres将经常“内联”这些功能 - 有效地扩展它们。您可以通过查看explain
输出来判断它们是否已被内联。
答案 1 :(得分:0)
你可以写:
where date_trunc('month', date) = date_trunc('month', current_date)
但是,Postgres不会使用索引来解析查询(如果有适当的索引可用)。