Fer*_*nte 3 sql postgresql between
我在Postgresql的不同字段中拥有一个包含年,月和日的表,但是我需要使用'between'这些字段进行查询.我尝试了一些疯狂的事情,但没有任何效果......有谁知道帮帮我?
防爆表:
CREATE TABLE my_table
(
id serial NOT NULL,
day integer NOT NULL,
month integer NOT NULL,
year integer NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)
作弊.您没有验证这些"日期",您只是对它们进行排序.验证是一项单独的任务,唯一合理的解决方案是架构更改.
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;
Run Code Online (Sandbox Code Playgroud)
如果您不想要巨大的差距,请使用 year*12*31 + month*31 + day
如果您坚持使用您的设计,这应该比目前提出的任何解决方案更简单,更快:ad-hoc行类型:
SELECT *
FROM tbl
WHERE (year, month, day) BETWEEN (2013,7,3)
AND (2013,7,5);
Run Code Online (Sandbox Code Playgroud)
但是,实际上,您应该使用正确的表格设计.将日期另存date为三integer列.
CREATE TABLE tbl (
tbl_id serial PRIMARY KEY
,thedate date NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
仍然至少和你的桌子一样快,因为来源较小.