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
子查询大于(>
)或小于(<
)时查询正常工作,但是当等于时,它不会显示任何结果。但它适用于:
HAVING (
SELECT SUM (revenue)
FROM TRANSACTION
WHERE TRANSACTION.campaign_id = T.ID
AND TRANSACTION.status = 3
AND deleted = 0
)::NUMERIC = 242.45
答案 0 :(得分:2)
猜测,revenue
为float4
或float8
,即float
或double precision
值。
正如@GáborBakos准确指出的那样,某些值(包括242.45)没有精确的二进制浮点表示。观察:
regress=> SET extra_float_digits = 3;
SET
regress=> SELECT FLOAT4 '242.45';
float4
------------
242.449997
(1 row)
通常,不应将浮点值与等式进行比较。请改用小范围。
请参阅:
您的查询适用于转化为NUMERIC
,因为与float4
或float8
不同,NUMERIC
是二进制编码的十进制类型,具有任意精度和比例。它可以精确地表示242.45
,并且不会受到舍入伪像和浮点数学的其他奇怪现象的影响。然而,这种演员表并不总是足够的 - 其他价值观可能仍未达到预期效果。考虑:
regress=> select (float4 '0.3' * 100000000) :: NUMERIC;
numeric
------------------
30000001.1920929
(1 row)
正如您所见,这些舍入错误可能会累积。
不应该依赖于与numeric
进行比较,而应该使用小范围比较而不是比较相等。或者,最重要的是,始终使用numeric
来表示财务和确切数量,永远不会浮点数。