我想编写一个查询来检索用户的id
,其birthyear
在当前年份或从表中递增为 -12 的所有年份Health_User
。以今年为例,将是 2018 年、2006 年、1994 年、1982 年出生的用户......我希望查询足够通用,可以在任何年份使用,而无需重置当前年份。
我的方法写在下面:
CREATE SEQUENCE years MAXVALUE EXTRACT (YEAR FROM current_date) INCREMENT -12;
SELECT id, EXTRACT (YEAR FROM birthyear)
FROM Health_User
WHERE EXTRACT (YEAR FROM birthyear) IN (years);
Health_User
中的birthyear
是
但是,它会在第一行返回一个错误:"语法错误在'EXTRACT'或附近"。有人会建议我如何修改我的查询吗?
已阅读:
- 创建序列
- 在选择中生成序列号
您不会出于查询目的创建。语法也无效,因为无法将表达式传递给实用程序命令。(您看到的错误的原因。它将在如下SEQUENCE
DO
语句中与动态 SQL 一起使用:
DO
$$BEGIN
EXECUTE format('CREATE SEQUENCE years MAXVALUE %s INCREMENT -12', EXTRACT(YEAR FROM now()));
END$$;
但不是为了这个目的。请改用generate_series()
:
SELECT u.* -- or just the columns you need
FROM generate_series(0, 12) g -- nobody's older than 144 years ...
JOIN Health_User u ON u.birthyear
= (date_trunc('year', now()) - interval '12 years' * g)::date;
随时动态工作。
此查询可以在(birthyear)
上使用纯索引 - 而原始查询不能,因为谓词不是"可优化的"。
旁白:
Health_User
中的birthyear
是时间戳格式的列,始终是用户出生年份的 1 月 1 日。
应该是date
或普通integer
,而不是timestamp
。
无论哪种方式,请记住,date_trunc()
和要date
的演员阵容也取决于当前的时区设置。
- 在 Rails 和 PostgreSQL 中完全忽略时区
您也可以直接生成带有generate_series()
时间戳。考虑:
- 在PostgreSQL中生成两个日期之间的时间序列