Select 给定序号中的值

Select values in given sequential numbers

我想编写一个查询来检索用户的 id,其 birthyear 在当前年份或所有从 Health_User 递增 -12 的年份 table。以今年为例,应该是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 in Health_Usertimestamp 日期格式的一列(感谢 Erwin Brandstetter 的提醒),它始终是所在年份的 1 月 1 日用户出生。

但是,returns 第一行出现错误:"syntax error at or near 'EXTRACT'"。有人会建议我如何修改我的查询吗?

已阅读:

您不会像这样创建 SEQUENCE for the purpose of a query. The syntax is also invalid since you cannot pass an expression to the utility command. (The reason for the error you see.) It would work with dynamic SQL in a DO 语句:

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 in Health_User is a column in timestamp format which is always January 1st of the year in which the user was born.

应该是 date 或普通 integer,而不是 timestamp

无论哪种方式,请记住 date_trunc() 和转换为 date 也取决于当前时区设置。

  • Ignoring timezones altogether in Rails and PostgreSQL

您也可以直接使用 generate_series() 生成时间戳。考虑:

  • Generating time series between two dates in PostgreSQL