sql - 带有时区顺序的 OSX postgres 9.1.4 时间戳

标签 sql postgresql timezone

在 OSX 10.8 on postresql server 9.1.4 上是一个意外的行为。 因为在 Ubuntu 12.04 上它是正确的。

要重现此问题,请使用以下 postgres sql 示例数据库。 笔记: 时间戳值是在时区“欧洲/柏林”中选择的,时间戳在 2012 中的夏令时结束前后。这就是这个测试的情况。

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-28 02:00:00 ║

因为我想要给定 (2012-10-28T02:30:00.000+01) 时间戳之前的最后一个时间戳。 但结果包含:

║ 204 ║ 2012-10-28 02: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-28 02:00:00+01 ║

为什么操作系统版本之间存在差异? 在这种情况下,此查询的答案“204”确实是错误的。 但是,如果我将时间戳映射到时区,为什么结果集会有所不同呢?据我所知,postgresql 在内部使用 UTC 来存储时间戳。所以夏令时在时间线上应该不是问题。 为什么会这样?

提前致谢,希望得到回复。

最佳答案

之前的答案是错误的。

基于您的数据。两个答案都很好。

在 2012 年 10 月 28 日,时间从夏令时更改为冬令时 ( Here it is explained )。

查看此结果中的小时数:

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 的记录在 berlin 列中具有相同的值。

阅读来自 here 的问题和答案.

如果你想按 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;

关于sql - 带有时区顺序的 OSX postgres 9.1.4 时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13961732/

相关文章:

sql - 类别的递归选择

sql - SQL数据库中的维度和单元分析

postgresql - 遍历记录时访问同名列

web-applications - 如何在我的网络应用程序中处理时区?

sql - 在关系数据库中存储分层数据有哪些选项?

mysql - SQL UPDATE 和 IF 语句

c# - SQL to Linq 在分组依据中选择多列

c - date 和 strftime 的时区从何而来?

r - 无效的 'tz' 值,时区问题

mysql - 使用带有数字查找的 having 子句