我想编写一个查询来检索用户的
id
,其birthyear
位于当年或从Health_User
表中增量为-12的所有年份。以今年为例,这将是出生于 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);
birthyear
中的Health_User
是但是,它返回一个错误:第一行“在‘EXTRACT’处或附近存在语法错误”。有人会建议我如何修改我的查询吗?
已读:
。该语法也是无效的,因为您无法将 expression 传递给实用程序命令。 (您看到错误的原因。)它会在SEQUENCE
DO
语句中与动态SQL一起使用,如下所示:
DO
$do$
BEGIN
EXECUTE format('CREATE SEQUENCE years MAXVALUE %s INCREMENT -12', EXTRACT(YEAR FROM now()));
END
$do$;
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)
上使用普通索引 - 而原始查询则不能,因为谓词不是 “sargable”。
旁白:
中的birthyear
是时间戳格式的列,始终为用户出生年份的1月1日。Health_User
应该是
date
或普通的 integer
,而不是 timestamp
。
无论哪种方式,请记住
date_trunc()
和到 date
的转换也取决于当前时区设置。
您还可以直接使用
generate_series()
生成时间戳。考虑: