2016-09-22 357 views
1

最近,我被StackOverflow用戶告知,使用BETWEEN運算符的值爲數據類型timestamp without time zone不應該使用。以下是報價。在Postgres中使用BETWEEN運算符與時間戳值

平均值> =和< =,不得與包含時間戳的範圍一起使用。

當被問及對本文或者Postgres的文檔的鏈接的說明,它指出,我得到的回答說

爲什麼會這麼簡單的東西需要用文檔的站點。我相信你可以找到很多無論如何,如果你谷歌(至少我在各種論壇上展示的情況下我的詳細帖子)

嗯,我用Google搜索。並沒有發現任何建議不要使用帶有時間戳值的運算符。實際上SO上的this answer使用它們,this mailing group post也是如此。

我被告知,這些年來我做錯了。這是真的嗎?

據我所知,Postgres的時間戳最大精度爲1 microsecond - 糾正我,如果我錯了。因此,下面的陳述不等於?

sample_date BETWEEN x AND y::timestamp - INTERVAL '1 microsecond' 

sample_date >= x AND sample_date < y 

編輯:樣品只是一個考慮的差異。我意識到開發人員可能會錯過時間部分,但假設一個人知道它的行爲如何,爲什麼它不應該使用?一般來說,這只是一個樣本,但我想知道更大的範圍。我一直在調查策劃者,它似乎在解析BETWEEN>= AND <=

爲什麼最好在結果中寫下>= AND <=而不是BETWEEN - 不包括翻譯時間?

+0

第二種方式更可取。它不會對底層實現做任何假設(加上它更短,更易於閱讀)。這裏有一篇關於在SQL Server中使用'between'的博客文章。許多觀點也適用於Postgres:http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx。 –

+0

@GordonLinoff感謝您的意見。這個例子只是考慮兩個語句之間的區別。這裏的主要問題是詢問用戶是否正確地指出BETWEEN不應該(通常)與時間戳一起使用 - 而不僅僅是提到的情況。我會確保閱讀那篇文章,再次感謝。 –

+1

你可以使用它,但它很笨拙和醜陋,而且由於它使用了epsilon'a BETWEEN a和b-epsilon',它將取決於epsilon。半開區間't> = c1 AND t = c2 AND t2 = c1 AND t joop

回答

1

使用ts BETWEEN validfrom AND validto而不是ts >= validform AND ts <= validto絕對沒有錯。他們是一樣的。

我只能猜測,但我會說,警告的目標不同,即上述(相同)條款是否是正確的使用。

現在這當然取決於你正在嘗試做什麼,但是很多時候這樣的子句用於標識特定時間戳的一個有效行。在這種情況下,上面的子句是錯誤的,因爲對於值爲ts的行更改時,您將獲得兩個結果。

考慮一下:

CREATE TABLE names (
    id integer PRIMARY KEY, 
    val text NOT NULL, 
    validfrom timestamptz NOT NULL, 
    validto timestamptz NOT NULL 
); 

INSERT INTO names VALUES (1, 'Smith', '1985-05-02 00:00:00', '2009-01-30 00:00:00'); 
INSERT INTO names VALUES (2, 'Jones', '2009-01-30 00:00:00', 'infinity'); 

這意味着是一個人的名字的歷史化表。

如果您使用的是WHERE條款像上面查詢的名稱在一定的時間有效,它會很好的工作

SELECT val FROM names 
WHERE current_timestamp BETWEEN validfrom AND validto; 

但它會做錯誤的事情

SELECT val FROM names 
WHERE '2009-01-30' BETWEEN validfrom AND validto; 

這是因爲名稱有效期間的終點是而不是部分區間。對於這種情況,寫下如下內容是正確的:

SELECT val FROM names 
WHERE '2009-01-30' >= validfrom AND '2009-01-30' < validto; 
+0

我想指出的是,這個問題是關於__一般建議不要在時間戳中使用BETWEEN_。你的例子給出了我很清楚的東西。我甚至寫道,Postgres時間戳的精度是1微秒。你提出的兩個陳述在結果上都不相等,但在我的例子中它們是。 :-) –

+0

我在第一段回答了你的問題---使用BETWEEN沒有任何問題。其餘的只是試圖解釋爲什麼這個概念可能會出現「BETWEEN」有問題。 –

+0

謝謝。如果是這樣的話,那麼似乎有人沒有真正理解我。 。 。 –