我在 Postgresql 的不同字段中拥有一个包含年、月和日的表,但我需要使用“介于”这些字段之间进行查询。我尝试了一些疯狂的事情,但没有任何效果......有人知道帮助我吗?
防爆表:
CREATE TABLE my_table
(
id serial NOT NULL,
day integer NOT NULL,
month integer NOT NULL,
year integer NOT NULL,
)
我在 Postgresql 的不同字段中拥有一个包含年、月和日的表,但我需要使用“介于”这些字段之间进行查询。我尝试了一些疯狂的事情,但没有任何效果......有人知道帮助我吗?
防爆表:
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
在坚持您的设计的同时,这应该比迄今为止提出的任何解决方案都更简单、更快:临时行类型:
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))
)
这真的会破坏任何索引搜索的机会。您可能每次都会扫描整个表。
寻找使用真实日期字段会好一百万倍。
我永远不想发布上面的代码,更不用说让同行评审了。我会感到羞愧的。