2014-06-05 85 views
1
SELECT 
T . ID, 
T . NAME, 
T .feed_id, 
T .status, 
T .budget, 
(
    SELECT 
     COUNT (*) 
    FROM 
     segment 
    WHERE 
     segment.campaign_id = T . ID 
) AS total_segments, 
(
    SELECT 
     SUM (revenue) 
    FROM 
     TRANSACTION 
    WHERE 
     TRANSACTION .campaign_id = T . ID 
    AND TRANSACTION .status = 3 
    AND deleted = 0 
) AS projected_revenue 
    FROM 
campaign T 
WHERE 
(T .deleted = 0) 
AND (site_id = 3) 
GROUP BY 
T ."id" 
    HAVING 
    (
    SELECT 
     SUM (revenue) 
    FROM 
     TRANSACTION 
    WHERE 
     TRANSACTION .campaign_id = T . ID 
    AND TRANSACTION .status = 3 
    AND deleted = 0 
    ) > 242.45 
     ORDER BY 
    T . ID DESC 

查詢怪異的結果正常工作時having子查詢比(>)大於或小於(<),但等於當它不顯示任何結果。但它的工作原理:對PostgreSQL的having子句

HAVING (
    SELECT SUM (revenue) 
    FROM TRANSACTION 
    WHERE TRANSACTION.campaign_id = T.ID 
    AND TRANSACTION.status = 3 
    AND deleted = 0 
)::NUMERIC = 242.45 
+2

是否可以通過NUMERIC類型說明符在較小的時間間隔內進行比較? ('242.45'不能表示爲有限的二進制數。) –

+0

@GáborBakos'NUMERIC'是二進制編碼的十進制數。 –

回答

2

在猜測,revenuefloat4float8,即一個floatdouble precision值。

正如@GáborBakos準確地指出的那樣,某些值(包括242.45)沒有準確的二進制浮點表示。觀察:

regress=> SET extra_float_digits = 3; 
SET 
regress=> SELECT FLOAT4 '242.45'; 
    float4 
------------ 
242.449997 
(1 row) 

通常,您不應該比較浮點值是否相等。改用小範圍。

請參見:

您的查詢與鑄造工程NUMERIC因爲不像float4float8NUMERIC是一個具有任意精度和比例的二進制編碼的十進制類型。它可以精確地表示242.45,它不會受到舍入僞像和其他浮點數學怪異的影響。然而,演員陣容並不總是足夠的 - 其他價值觀可能仍然不能滿足你的期望。考慮:

regress=> select (float4 '0.3' * 100000000) :: NUMERIC; 
    numeric  
------------------ 
30000001.1920929 
(1 row) 

正如你可以看到那些舍入誤差可以積累。

而不是依靠與numeric比較,你應該真的使用小範圍比較,而不是比較平等。或者,最重要的是,始終使用numeric來表示財務和確切數量,從不浮點數。

+0

謝謝先生@克雷格林格 –

+0

非常感謝這個鏈接簡單明瞭http://www.peterbe.com/plog/comparing-real-values –