0

我的表有一个类别“时间戳”,其中时间戳的格式为 2015-06-22 18:59:59

但是,使用 DBVisualizer Free 9.2.8 和 Vertica,当我尝试按时间戳提取行时,

SELECT * FROM table WHERE timestamp = '2015-06-22 18:59:59';

(直接复制粘贴邮票),什么都没有出现。为什么会发生这种情况,有没有办法解决它?

4

1 回答 1

2

仅供参考,如果您确实使用的是 TIMESTAMP 类型,则说“时间戳的格式为 2015-06-22 18:59:59”是不正确的。这些类型有自己的日期时间值的内部表示,几乎总是自epoch以来的计数。在您使用 Vertica 的情况下,此类存储使用 8 个字节。日期时间值的格式化发生在生成字符串表示时。切勿将字符串表示与日期时间值混淆。将两者混为一谈很可能与您的问题/困惑有关。

关于可能的问题的一些不同的想法......</p>

字符串文字

您确定 Vertica 将字符串作为时间戳文字吗?您使用的格式是常见的 SQL 格式。但鉴于 Vertica 似乎是一个专门的数据库,我会仔细检查一下。

如果不允许使用字符串,您可能需要调用某种函数将字符串转换为日期时间值。

小数秒

正如Martin Smith的评论所指出的,Vertica 7.1 中与时间戳相关的数据类型的文档说,这些类型的分辨率可以达到微秒的小数秒。这意味着最多 6 位小数。

因此,如果您正在搜索“2015-06-22 18:59:59”但存储的值为“2015-06-22 18:59:59.012345”,则查询不匹配。

半开

上面描述的小数秒问题通常是人们在处理时间跨度时遇到问题的原因。如果你天真地试图确定结束时间,你可能会遇到问题。在您的示例字符串中看到“59:59”让我认为这适用于您。

更好的时间跨度方法是“半开放”(或半封闭,无论如何),其中开始是包容性的,而结束是排斥性的。常见的符号是[). 在比较逻辑中,这意味着:value >= start AND value < stop。请注意比较中缺少等号stop。在英语中,我们会说“查找从下午 2:00 开始到(但不包括)下午 3:00 的一个小时的发票”。

一周半开是指周一至周一,一个月是一个月的第一天到下一个月的第一天,一年是一年的 1 月 1 日到下一年的 1 月 1 日。

半开意味着不在SQL 中使用BETWEEN。SQLBETWEEN经常受到批评。相反,请执行以下操作来查找一个小时的发票。请注意Z字符串文字末尾的“UTC 时区”(“Z”代表“Zulu”)。(但请验证,因为我的 SQL 语法可能需要修复。)

SELECT * 
FROM some_table_
WHERE invoice_received_ >= '2015-06-22 18:00:00Z'
AND invoice_received_ < '2015-06-22 19:00:00Z'
;

此查询将捕获任何值,例如 '2015-06-22 18:59:59.654321" 这似乎在逃避你。

保留字

我希望您还没有真正将您的表命名为“表”和您的列“时间戳”。这种关键字和保留字的使用可能会导致明显的错误或更微妙的奇怪问题。

提示:避免各种数据库中超过一千个保留字中的任何一个的简单方法是在结尾添加下划线。SQL 标准明确承诺永远不会在其保留字中使用尾随下划线。所以使用“timestamp_”而不是“timestamp”。另一个例子:“invoice_”表和“received_”列。我建议对 SQL 中所有你的名字都习惯这样做:列、表、约束、索引等等。

时区

您正在使用TIMESTAMPwhich 的缩写TIMESTAMP WITHOUT TIME ZONE。或者我认为;Vertica 文档含糊不清,但这是Postgres 文档中常见的用法,甚至可能是标准 SQL。

无论如何,TIMESTAMP WITHOUT TIME ZONE对于大多数商业目的来说,通常是错误的类型。时区被WITH错误命名并经常被误解:它意味着“关于时区”,其中包含来自UTC的偏移量或其他时区信息的数据输入在 INSERT/UPDATE 操作期间被调整为 UTC。该WITHOUT类型简单地忽略任何此类偏移或时区信息。

WITHOUT类型通常只能用于日期时间的概念,而不受任何一个地方的约束。例如,说“今年的圣诞节从 2015 年 12 月 25 日开始”。这意味着在任何时区而不是特定时区。例如,显然圣诞节在巴黎比在蒙特利尔更早开始。

如果您要为发票等法律文件添加时间戳,或与跨时区的人进行预约,或在不同地区安排发货,您应该使用WITH时区类型。

回到您可能遇到的问题:测试 Vertica 或您的客户端应用程序或您的数据库驱动程序如何处理您的输入字符串。它可能会调整时区,作为使用客户端计算机当前默认时区解析字符串的一部分。发送到数据库时,如果在存储期间未对 UTC 进行调整,则该值将与存储的值不匹配。

提示:通常最佳实践是在 UTC 中执行所有存储和业务逻辑,仅在用户期望的地方调整到本地时区。

于 2015-07-11T23:33:55.630 回答