2012-01-01 67 views
3

我運行一個查詢是這樣的:PostgreSQL的間隔誤差

SELECT (SELECT expire_date FROM "License" WHERE license_id = 10) 
     - interval '1 mon 133 days 22:19:49.191748' 

所有的一切都很好。
但當我嘗試這個辦法:

SELECT (SELECT expire_date FROM "License" WHERE license_id = 10) 
     - interval ((SELECT expire_date-now() FROM "License" WHERE license_id = 10) 
       + interval '1 months') 

我得到一個錯誤:

ERROR: syntax error at or near "(" 
LINE 1: ...FROM "License" WHERE license_id = 10) - interval ((SELECT ex... 
                  ^

請幫忙,謝謝。

+0

你在計算什麼?您的子查詢(可能)不是必需的。第一個「間隔」關鍵字不是必需的。如果我遵循括號,那麼無論「x」的值如何,你似乎都在計算'x - ((x - NOW)+'1 month')',即1個月前。 – pilcrow 2012-01-01 18:59:34

回答

2

我的理解是Postgres allowstype 'string'語法用於指定簡單文字常量的類型。對於其他任何你必須使用...::typeCAST (... AS type)

+0

我試過SELECT(SELECT expire_date FROM「License」WHERE license_id = 10) - interval((SELECT expire_date-now()FROM「License」WHERE license_id = 10)+ interval'1 months'):: character varying 但仍然獲取錯誤 – Ahmad 2012-01-01 13:59:20

+0

'SELECT(SELECT expire_date FROM「License」WHERE license_id = 10) - ((SELECT expire_date-now()FROM「License」WHERE license_id = 10)+ interval'1 months'):: interval'就是你想要的。 – 2012-01-01 14:28:10

1

你的第一個查詢等效於:

SELECT expire_date - interval '1 mon 133 days 22:19:49.191748' as expire_date 
FROM "License" 
WHERE license_id = 10 

二(雖然可能會無法運行):

SELECT expire_date - (expire_date-now() + interval '1 months') 
FROM "License" 
WHERE license_id = 10 

因此,最好這樣寫:

SELECT now() - interval '1 months' 
FROM "License" 
WHERE license_id = 10 
1

我想你的第二個查詢就相當於這個。我可能是錯的。

SELECT (SELECT expire_date 
     FROM "License" WHERE license_id = 10) 

    - (SELECT expire_date - now() + interval '1 months' 
     FROM "License" WHERE license_id = 10); 
1

可以簡化爲:

SELECT expire_date - (expire_date - now()) - interval '1 month' 
FROM "License" 
WHERE license_id = 10 

這是有效的,而不額外括號中,因爲減法從左到右評估。
雖然,在我的第一個版本中,一個必要的括號對缺失。

這種查詢形式還可以防止在license不應該是唯一的情況下發生錯誤。你會得到多行。在這種情況下,如果您需要它,請添加LIMIT 1保證一個值。


@Milen診斷錯誤的原因正確。試驗這些陳述看看:

SELECT interval (interval '1 month'); -- error 
SELECT (interval '1 month')::interval; -- no error 

但是,治療更簡單。只是不要添加另一個演員,這是多餘的。