2016-01-20 47 views
1

我有一個values表,例如:恢復之前的幾個值幾個指定的日期

id | user_id | value | date 
--------------------------------- 
1 |  12 | 38 | 2014-04-05 
2 |  15 | 19 | 2014-04-05 
3 |  12 | 47 | 2014-04-08 

我想檢索所有值指定的日期。但是,如果我沒有一個特定日期的值,我想獲取以前的可用值。例如,上述數據集,如果我查詢日期2014-04-072014-04-08用戶12個值,我需要找回38和47

我成功了使用兩個查詢:

SELECT * 
FROM values 
WHERE date <= $date 
ORDER BY date DESC 
LIMIT 1 

然而,每次需要dates.length請求。所以,我想知道是否有任何更高性能的解決方案來檢索單個請求中的所有值?

+0

你是什麼意思的'dates.length'請求? – Patrick

+0

如果我有兩個日期,那麼我需要2個請求像上面那樣。如果我有10個,那麼它需要10個請求。每次我都會獲得5到10個日期。 –

回答

1

通常,您可以使用VALUES子句在單個查詢中指定多個值。

如果你只是偶爾日期失蹤(和日期行之間的任何特定user_id因此沒有很大的差距),那麼這將是一個完美的解決方案:

SELECT dt, coalesce(value, lag(value) OVER (ORDER BY dt)) AS value 
FROM (VALUES ('2014-04-07'::date), ('2014-04-08')) AS dates(dt) 
LEFT JOIN "values" ON "date" = dt AND user_id = 12; 

lag()window function採以前value如果當前行沒有value

如果,另一方面,可能有很大的差距,需要做更多的工作:

SELECT DISTINCT dt, first_value(value) OVER (ORDER BY diff) AS value 
FROM (
    SELECT dt, value, dt - "date" AS diff 
    FROM (VALUES ('2014-04-07'::date), ('2014-04-08')) AS dates(dt) 
    CROSS JOIN "values" 
    WHERE user_id = 12) sub; 

在這種情況下,CROSS JOINuser_id = 12VALUES子句中的日期之間的差異作出並在一個子查詢中計算表格行。所以每行都有一個值爲value的值。在主要查詢中,使用first_value()窗口函數選擇具有最小差異的value。請注意,訂購diff並選取第一行在此不起作用,因爲您希望返回多個日期的值。

+0

非常感謝!它完美的作品。我確信PSQL中有一個特定的功能,事實上:我發現了Window函數的世界。 :) –