我有一个表保存日期的PostgreSQL数据库。 现在,我需要找到日期范围内的所有行15/02
至21/06
所有年(日/月)。
实施例的结果:
1840-02-28
1990-06-21
1991-02-15
1991-04-25
1992-05-30
1995-03-04
1995-04-10
2001-02-03
2010-04-06
我有一个表保存日期的PostgreSQL数据库。 现在,我需要找到日期范围内的所有行15/02
至21/06
所有年(日/月)。
实施例的结果:
1840-02-28
1990-06-21
1991-02-15
1991-04-25
1992-05-30
1995-03-04
1995-04-10
2001-02-03
2010-04-06
假设你想在今年一年中,无论某些天之间的日期(例如,如果你发送了一批的生日卡或某事)(与信仰的飞跃),你可以设置这个测试:
CREATE TABLE d (dt date);
COPY d FROM STDIN;
1840-02-28
1990-06-21
1991-02-15
1991-04-25
1992-05-30
1995-03-04
1995-04-10
2001-02-03
2010-04-06
\.
您还可以使用“行值构造”可以轻松地选择所需的范围:
SELECT * FROM d
WHERE (EXTRACT(MONTH FROM dt), EXTRACT(DAY FROM dt))
BETWEEN (2, 15) AND (6, 21);
这将产生:
dt ------------ 1840-02-28 1990-06-21 1991-02-15 1991-04-25 1992-05-30 1995-03-04 1995-04-10 2010-04-06 (8 rows)
使用WHERE
子句与BETWEEN
操作。 看到:
http://www.postgresql.org/docs/current/static/functions-comparison.html#FUNCTIONS-COMPARISON
和:
http://www.postgresql.org/docs/current/static/sql-select.html http://www.postgresql.org/docs/current/static/tutorial.html
如果没有帮助,请扩展您的问题有:
\d tablename
命令或原始CREATE TABLE
语句; 您可以使用下面的语法。
SELECT * FROM tableName WHERE dateColumnName BETWEEN '2012.01.01' AND '2012.08.14';
只需更换以下;
tableName - Name of the table you are going to access
dateColumnName - Name of the column whch contains dates
2012.08.1 - Start date
2012.08.21 - End date
当进入这两个日期,仔细检查上面的例子。 输入相同的格式,并且附上他们内部的''
秒。
如果您要更换*
标记与列名,您可以过滤出列的值。
希望帮助..
我敢肯定,这个问题的@ kgrittn的解释是正确的,我爱他优雅的使用排构造函数。 我测试了几个选择更是如此后,没有一个可以匹配的性能:
与65426行的实际生活台试验; 32107合格。 PostgreSQL的9.1.4,最好的五连EXPLAIN ANALYZE
:
SELECT * FROM tbl
WHERE to_char(data, 'MMDD') BETWEEN '0215' AND '0621';
总运行时间:251.188毫秒
SELECT * FROM tbl
WHERE to_char(data, 'MMDD')::int BETWEEN 215 AND 621;
总运行时间:250.965毫秒
SELECT * FROM tbl
WHERE to_char(data, 'MMDD') COLLATE "C" BETWEEN '0215' AND '0621';
总运行时间:221.732毫秒
字符串比较是与“非现场”更快C
-更多在大约核对支持手动 。
SELECT * FROM tbl
WHERE EXTRACT(MONTH FROM data)*100 + EXTRACT(DAY FROM data)
BETWEEN 215 AND 621;
总运行时间:209.965毫秒
SELECT * FROM tbl
WHERE EXTRACT(MONTH FROM data) BETWEEN 3 AND 5
OR EXTRACT(MONTH FROM data) = 2 AND EXTRACT(DAY FROM data) >= 15
OR EXTRACT(MONTH FROM data) = 6 AND EXTRACT(DAY FROM data) <= 21;
总运行时间:160.169毫秒
SELECT * FROM tbl
WHERE EXTRACT(MONTH FROM data) BETWEEN 2 AND 6
AND CASE EXTRACT(MONTH FROM data)
WHEN 2 THEN EXTRACT(DAY FROM data) >= 15
WHEN 6 THEN EXTRACT(DAY FROM data) <=21
ELSE TRUE END;
总运行时间:147.390毫秒
SELECT * FROM tbl
WHERE CASE EXTRACT(MONTH FROM data)
WHEN 3 THEN TRUE
WHEN 4 THEN TRUE
WHEN 5 THEN TRUE
WHEN 2 THEN EXTRACT(DAY FROM data) >= 15
WHEN 6 THEN EXTRACT(DAY FROM data) <= 21
ELSE FALSE END;
总运行时间:131.907毫秒
@凯文与排构造的解决方案:
SELECT * FROM tbl
WHERE (EXTRACT(MONTH FROM data), EXTRACT(DAY FROM data))
BETWEEN (2, 15) AND (6, 21);
总运行时间:125.460毫秒
起首。
击败唯一的方法是使用索引。 查询的无上述可以使用一个普通的索引data
。 但是,如果读取性能是至关重要的(并在写入性能一部小成本),你可以再打一个函数索引 :
CREATE INDEX ON tbl(EXTRACT(MONTH FROM data), EXTRACT(DAY FROM data));
SELECT * FROM tbl
WHERE (EXTRACT(MONTH FROM data), EXTRACT(DAY FROM data))
BETWEEN (2, 15) AND (6, 21);
总运行时间:85.895毫秒
而这也正是我终于可以用吹风击败了凯文的查询:与单个列的索引,而不是在他的案件所需要的多列索引。
CREATE INDEX ON tbl(
CAST(EXTRACT(MONTH FROM data) * 100 + EXTRACT(DAY FROM data) AS int));
SELECT * FROM tbl
WHERE (EXTRACT(MONTH FROM data) * 100 + EXTRACT(DAY FROM data))::int
BETWEEN 215 AND 621;
总运行时间:84.215毫秒
您可以使用简单的条件> =和<=或类似的或使用之间/和,但关键是要知道你的确切数据类型。 有时日期字段包含时间,这正是因此建议使用一些最新相关功能排除时间问题,查询可能会出错。 在SQL Server公共功能要做到这一点是DATEDIFF函数。