[英]Creating queries using between for year, month and day in separate fields
我在Postgresql的不同字段中拥有一个包含年,月和日的表,但我需要使用'between'这些字段进行查询。 我尝试了一些疯狂的事情,但没有任何效果......有谁知道帮帮我?
防爆表:
CREATE TABLE my_table
(
id serial NOT NULL,
day integer NOT NULL,
month integer NOT NULL,
year integer NOT NULL,
)
作弊。 您没有验证这些“日期”,您只是对它们进行排序。 验证是一项单独的任务,唯一合理的解决方案是架构更改。
CREATE INDEX my_table__date__idx ON test1 (year * 10000 + month * 100 + day);
SELECT *
FROM my_table
WHERE year * 10000 + month * 100 + day BETWEEN 20130101 AND 20131231;
如果您不想要巨大的差距,请使用year*12*31 + month*31 + day
如果您坚持使用您的设计,这应该比目前提出的任何解决方案更简单,更快 : ad-hoc行类型 :
SELECT *
FROM tbl
WHERE (year, month, day) BETWEEN (2013,7,3)
AND (2013,7,5);
但是,实际上,您应该使用正确的表格设计 。 将日期保存为date
,而不是三个integer
列。
CREATE TABLE tbl (
tbl_id serial PRIMARY KEY
,thedate date NOT NULL
)
thedate
包括所有三列: day
, month
, year
,需要4个字节,如integer
。
那么你的工作将是微不足道的:
要获取日,月,年 - 或周等,请使用to_char()
或extract()
或date_trunc()
。 这些功能非常快速且通用。
例如,您可以创建一个看起来与您现在的表完全相同 的VIEW
:
CREATE view old_table AS
SELECT tbl_id
,EXTRACT(day FROM thedate)::int AS day
,EXTRACT(month FROM thedate)::int AS month
,EXTRACT(year FROM thedate)::int AS year
FROM my_table;
仍然至少和你的桌子一样快,因为来源较小。
如果您无法更改表结构以使用正确的日期,则可以从字段中创建日期以进行比较,例如:
SELECT *
FROM Table
WHERE to_date(Year||' '||Day||' '||Month, 'YYYY DD MM') BETWEEN date1 AND date2
如果它们都是整数,你必须将每个转换为字符串,我相信::VARCHAR()
可以工作,或者CAST()
:
SELECT *
FROM Table
WHERE to_date(Year::varchar(4)||' '||Day::varchar(2)||' '||Month::varchar(2), 'YYYY DD MM') BETWEEN date1 AND date2
WHERE
(
((day >= :first_day) AND (month = :first_month) AND (year = :first_year))
OR ( (month > :first_month) AND (year = :first_year))
OR ( (year > :first_year))
)
AND
(
((day <= :final_day) AND (month = :final_month) AND (year = :final_year))
OR ( (month < :final_month) AND (year = :final_year))
OR ( (year < :final_year))
)
这真的会破坏索引寻求的任何机会。 您可能每次都会扫描整个表格。
想要使用真实的日期字段,你要好一百万倍。
我永远不想发布上面的代码,没关系有同行评审它。 我会感到羞愧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.