我想写一个查询,从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
是时间戳日期格式的列(感谢Erwin Brandstetter的提醒),该列始终是用户出生年份的1月1日。但是,它返回一个错误:第一行的“EXTRACT”处或附近出现语法错误。有人能建议我如何修改我的问题吗?
已阅读:
CREATE SEQUENCE
Generate sequence number in select
最佳答案
您不会为查询创建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)
上使用普通索引,而原始查询不能,因为谓词不是"sargable"。旁白:
birthyear
中的Health_User
是时间戳格式的列,它始终是用户出生年份的1月1日。应该是
date
或普通integer
,而不是timestamp
。不管怎样,请记住
date_trunc()
和转换为date
也取决于当前时区设置。Ignoring timezones altogether in Rails and PostgreSQL
您还可以直接使用
generate_series()
生成时间戳。考虑:Generating time series between two dates in PostgreSQL