在Postgres中解析为'where'条件的宏?

时间:2016-12-04 00:15:14

标签: sql postgresql macros

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语句列表,返回列表中最后一个查询的结果。

让我觉得他们没有,我需要别的东西。

2 个答案:

答案 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不会使用索引来解析查询(如果有适当的索引可用)。