Postgresql
在更多/更少特定時間點返回值
在 PostgreSQL 10.0 中,我有一個包含兩列的大表:
CREATE TABLE xs ( ts timestamp with time zone NOT NULL, x integer NOT NULL )
現在,如果我有 100 個給定的時間點,我如何準確地返回 100 個在( )這些時間點
x
之前的 -es (對於這些時間點中的每一個)?<=
對於一個單一的,這將非常容易:
SELECT x FROM xs WHERE ts <= '2018-03-13 11:41:47.167973+00' LIMIT 1
但是如何有效地為 100 人做到這一點呢?就像是:
SELECT x FROM xs WHERE ts FIRST_LESS_THAN_EQUAL_IN ('2018-03-13 11:41:47.167973+00', '2018-03-13 11:41:47.198564+00', '2018-03-13 11:41:47.555668+00', ... '2018-03-13 11:41:57.766888+00')
顯然,在 上有一個索引
ts
。
我建議使用
LATERAL
子查詢,最好使用 aLEFT [OUTER] JOIN
來保留所有輸入行(顯示 NULL 值以防根本不匹配):SELECT v.reference_ts, t.most_recent_x FROM ( VALUES (timestamptz '2018-03-13 11:41:47.167973+00') -- type cast in first row , ('2018-03-13 11:41:47.198564+00') , ('2018-03-13 11:41:47.555668+00') , ('2018-03-13 11:41:57.766888+00') ) AS v(reference_ts) LEFT JOIN LATERAL ( SELECT x AS most_recent_x FROM xs WHERE ts <= v.reference_ts -- ts is unique (?!); see below ORDER BY ts DESC LIMIT 1 ) AS t ON true;
VALUES
表達式是將 100 個時間戳放入我們可以使用的派生表中的一種*方法。*獨立VALUES
表達式可能需要在第一行進行顯式類型轉換。看:還有其他方法可以傳遞您的值,例如數組(或轉換為的數組文字
timestamptz[]
)和unnest()
查詢:關於
LATERAL
子查詢:不要忘記,
ORDER BY
否則你會得到任意結果——比如 @a1ex07 評論。如果
ts
不是唯一的,則返回哪個重複項是未定義的,除非您添加更多ORDER BY
項目以使其具有確定性。喜歡:從任何一組同行ORDER BY ts DESC, x DESC
中獲得最大的行。x
並使索引匹配。一個索引
(ts)
(就像你提到的那樣)對性能有奇效。或者,理想情況下,
(ts DESC, x)
如果滿足僅索引掃描的先決條件。dbfiddle在這裡