2015-07-10 108 views
0

我的表中有一類「時間戳」,其中時間戳被格式化2015年6月22日18時59分59秒SQL等於不適用於時間戳?

但是,使用DBVisualizer中免費9.2.8和Vertica的,當我嘗試通過時間戳與拉起行一個

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

(直接複製粘貼郵票),什麼都沒有出現。爲什麼會發生這種情況,並有解決辦法嗎?

+1

你正在使用哪些DBMS? –

+0

@NorbertvanNobelen這個問題被標記爲Vertica。 –

+1

從文檔Vertica時間戳有[1微秒的分辨率](https://my.vertica.com/docs/5.0/HTML/Master/datatype-datetime.html)實際上是否存在小數部分存儲未在您的顯示工具中顯示? –

回答

2

僅供參考,如果您確實使用TIMESTAMP類型,則說「時間戳格式設置爲2015-06-22 18:59:59」不正確。這種類型有自己的日期時間值的內部表示,自epoch以來幾乎總是一個計數。在您使用Vertica的情況下,8個字節用於存儲。當生成字符串表示時,日期時間值的格式發生。不要將字符串表示與日期時間值混淆。將兩者混爲一談可能與你的問題/困惑有關。

約可能出現的問題有幾個不同的想法...

字符串字面

確定Vertica的需要字符串作爲時間戳文字?您使用的格式是常用的SQL格式。但鑑於Vertica似乎是一個專門的數據庫,我會仔細檢查一下。

如果字符串不被允許,您可能需要調用某種函數將字符串轉換爲日期時間值。

分數其次

正如Martin Smith指出的評論中,doc for Timestamp-related data types in Vertica 7.1說,這些類型可以有小數第二至microseconds分辨率。這意味着多達小數點後6位小數。

因此,如果您正在搜索「2015-06-22 18:59:59」,但存儲值爲「2015-06-22 18:59:59.」,則查詢中不匹配。

半開

上述小數秒的問題往往是人們處理時間跨度時遇到問題的原因。如果您天真地嘗試確定結束時間,您可能會遇到問題。看到示例字符串中的「59:59」使我認爲這適用於您。

的更好方法的時間跨度是「半開」(或Half-Closed什麼的),剛開始是包容而結局是獨家。這種常見符號是[)。在比較邏輯中,這意味着:value >= start AND value < stop。請注意0​​比較中缺少EQUALS SIGN。用英文,我們會說:「從下午2點開始查找一小時的發票,上午3點,但不包括在內。

半周開放一週意味着星期一到星期一,一個月的第一個月到下一個月的第一個月,以及一年的1月1到第二年的1月1日。

半開是指而不是在SQL中使用BETWEEN。 SQL的BETWEENoften be criticized。而應該像下面這樣尋找一小時的發票。請注意字符串文字末尾的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年6月22日18:59:59.654321" ,這似乎是躲避你

保留字

我希望你還沒有真正命名您的表「表」和你的專欄「時間戳」這樣的關鍵字的使用和保留字可以引起明確的錯誤或更微妙奇怪的問題,

提示:簡單的方法來避免vario中的上千個保留字我們的數據庫是給追加一個尾隨下劃線。 SQL標準明確承諾從不在其保留字中使用尾隨下劃線。所以使用「timestamp_」而不是「timestamp」。再比如:「invoice_」表和「received_」列。我建議做爲的一切習慣你的名字在SQL中:列,表,約束,索引等等。

時區

您正在使用TIMESTAMP這是短期的TIMESTAMP WITHOUT TIME ZONE。或者我假設; Vertica doc很模糊,但這是Postgres doc中常見的用法,甚至可能是標準SQL。

總而言之,TIMESTAMP WITHOUT TIME ZONE通常是大多數商業用途的錯誤類型。 WITH時區出現錯誤名稱並經常被誤解爲:它意味着「尊重時區」,其中包含從UTC開始的偏移量或其他時區信息的數據輸入在INSERT/UPDATE操作期間調整爲UTC。 WITHOUT類型只需忽略任何這樣的偏移或時區信息。

WITHOUT類型只能用於日期時間的概念,通常不受任何一個地區的限制。例如,說「今年聖誕節從2015年12月25日開始」。這意味着在任何時區而不是特定的時區。例如,聖誕節早在巴黎,比在蒙特利爾開始。

如果您打印法定文檔(如發票或與跨時區人員預約約會或在各地安排裝運時間),則應使用WITH時區類型。

回覆您可能遇到的問題:測試Vertica或您的客戶端應用程序或您的數據庫驅動程序如何處理您的輸入字符串。它可能會調整時區,作爲使用客戶端機器當前默認時區解析字符串的一部分。發送到數據庫時,如果在存儲過程中未對UTC進行調整,則該值與存儲的值不匹配。

提示:通常情況下,最佳做法是以UTC爲單位執行所有存儲和業務邏輯,僅在用戶期望的地方根據當地時區進行調整。