在poStresql Server上的OSX 10.8是一个意外的行为。因为在Ubuntu上12.04上是正确的。
重现此问题,请使用以下Postgres SQL示例数据库。笔记:时间戳值是在"欧洲/柏林"时区选择的,时间戳在2012年的DST末端,这是该测试的情况。
BEGIN;
DROP TABLE data;
CREATE TABLE data (
"id" int8 NOT NULL,
"timestampwithtimezone" timestamp(6) WITH TIME ZONE,
CONSTRAINT "data_pkey" PRIMARY KEY ("id")
);
COMMIT;
BEGIN;
INSERT INTO data (id, timestampwithtimezone) VALUES (205,'2012-10-28 01:30:00+02');
INSERT INTO data (id, timestampwithtimezone) VALUES (204,'2012-10-28 02:00:00+02');
INSERT INTO data (id, timestampwithtimezone) VALUES (203,'2012-10-28 02:30:00+02');
INSERT INTO data (id, timestampwithtimezone) VALUES (202,'2012-10-28 02:59:59+02');
INSERT INTO data (id, timestampwithtimezone) VALUES (106,'2012-10-28 02:00:00+01');
INSERT INTO data (id, timestampwithtimezone) VALUES (107,'2012-10-28 02:30:00+01');
INSERT INTO data (id, timestampwithtimezone) VALUES (108,'2012-10-28 02:59:59+01');
INSERT INTO data (id, timestampwithtimezone) VALUES (109,'2012-10-28 03:00:00+01');
INSERT INTO data (id, timestampwithtimezone) VALUES (110,'2012-10-28 03:30:00+01');
COMMIT;
如果我键入以下SQL查询,该查询仅在给定时间戳之前查找最后存在的时间戳:
SELECT id, timestampwithtimezone at time zone 'Europe/Berlin' as timestampwithtimezone
FROM data
WHERE
timestampwithtimezone at time zone 'Europe/Berlin'
< cast('2012-10-28T02:30:00.000+01' AS timestamp)
ORDER BY timestampwithtimezone DESC
LIMIT 1;
我的预期结果是:
║106║2012-10-2802:00:00
由于我想要给定的最后时间戳(2012-10-28T02:30:00.000 01)时间戳。但是结果包含:
║204║2012-10-2802:00:00
在这种情况下,PostgreSQLS排序似乎是错误的。在Ubuntu下,我得到了正确的答案,该答案是ID:106而不是204。
但是:
如果我设置此查询:(唯一的区别是我将结果集映射到时区):
SELECT id, timestampwithtimezone
FROM data
WHERE timestampwithtimezone at time zone 'Europe/Berlin'
< cast('2012-10-28T02:30:00.000+01' AS timestamp)
ORDER BY timestampwithtimezone DESC
LIMIT 1;
OSX 10.8中的结果设置为预期以及Ubuntu 12.04:
║106║2012-10-2802:00:00 01
为什么OS版本之间有区别?在这种情况下,此查询的答案" 204"确实是错误的。但是,如果我将时间戳映射到时区,为什么结果集有差异呢?据我所知,PostgreSQL使用内部UTC存储时间戳。因此,在时间轴中,DST应该不是问题。为什么会发生这种情况?
预先感谢您的回应。
上一个答案是错误的。
基于您的数据。两个答案都很好。
在2012-10-28中,从夏季到冬季有时间变化(这里可以解释)。
查看此结果的小时:
select id,
timestampwithtimezone,
timestampwithtimezone at time zone 'Europe/Berlin' as berlin
from data
order by berlin ;
id | timestampwithtimezone | berlin
-----+------------------------+---------------------
205 | 2012-10-28 01:30:00+02 | 2012-10-28 01:30:00
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00
203 | 2012-10-28 02:30:00+02 | 2012-10-28 02:30:00
202 | 2012-10-28 02:59:59+02 | 2012-10-28 02:59:59
具有ID 204和106的记录在柏林列中具有相同的值。
阅读此处的问答。
如果您想通过Timestamptz订购,请不要将列以相同名称
使用别名SELECT
id,
timestampwithtimezone at time zone 'Europe/Berlin' as timestampwithtimezone_alias
FROM data
WHERE
timestampwithtimezone at time zone 'Europe/Berlin'
< cast('2012-10-28T02:30:00.000' AS timestamp)
ORDER BY timestampwithtimezone DESC
LIMIT 1;