数学运算
问题描述:
我们正在使用Oracle 10g XE,我们发现下面的查询不返回任何值:数学运算
SELECT ref.referencia,
ref.descripcio,
stock_reservat,
stock,
stock_p_rebre,
(SELECT count(*)
FROM ref_numeros_serie num
WHERE num.empresa=ref.empresa AND
num.referencia=ref.referencia AND
num.diposit=1 AND
nvl(num.actiu,'N')='S') cnt_nums_serie
FROM emp_referencies ref,
ref_stk_dip_acu stk
WHERE ref.empresa=1 AND
ref.referencia='1B' AND
stk.empresa=ref.empresa AND
stk.referencia=ref.referencia AND
stk.diposit=1 AND
-- Relevant part
(stk.stock - stk.stock_reservat) <> (SELECT count(*)
FROM ref_numeros_serie num
WHERE num.empresa=ref.empresa AND
num.referencia=ref.referencia AND
num.diposit=1 AND
nvl(num.actiu,'N')='S')
-- End of relevant part
GROUP BY ref.empresa,
ref.referencia,
ref.descripcio,
stk.stock,
stk.stock_reservat,
stock,
stock_p_rebre
所以减法和子查询之间的比较是假的。但是,如果我们将子查询和减法替换为这样:
SELECT ref.referencia,ref.descripcio,
stock_reservat,
stock,
stock_p_rebre,
(SELECT count(*)
FROM ref_numeros_serie num
WHERE num.empresa=ref.empresa AND
num.referencia=ref.referencia AND
num.diposit=1 AND
nvl(num.actiu,'N')='S') cnt_nums_serie
FROM emp_referencies ref,
ref_stk_dip_acu stk
WHERE ref.empresa=1 AND
ref.referencia='1B' AND
stk.empresa=ref.empresa AND
stk.referencia=ref.referencia AND
stk.diposit=1 AND
-- Relevant part
(SELECT count(*)
FROM ref_numeros_serie num
WHERE num.empresa=ref.empresa AND
num.referencia=ref.referencia AND
num.diposit=1 AND
nvl(num.actiu,'N')='S') <> (stk.stock - stk.stock_reservat)
-- End of relevant part
GROUP BY ref.empresa,
ref.referencia,
ref.descripcio,
stk.stock,
stk.stock_reservat,
stock,
stock_p_rebre
比较结果是真实的,我们得到结果。
我们已经尝试了以下情况:
- 卸下减法因此比较的左边部分的第二部分是
stk.stock
:我们得到的成绩,正确 - 通过改变减法的第二部分许多这样的
stk.stock-2
:我们得到的成绩,正确 - 交换比较的左边和右边部分,上面解释说:我们得到的成绩,正确
- 更改算术运算符这样
(stk.stock+stk.stock_reservat) <> subquery
:没有结果,不正确 - 由许多这样
(stk.stock-stk.stock_reservat) <> 2
更改子查询:我们得到
我们尝试了这些案件与10g的非XE数据库结果,正确的,它具有相同的行为。另一方面,使用11g,它工作得很好。
因此,我们的结论是,使用Oracle 10g时,两列之间的算术运算与子查询之间的比较仅在子查询位于左侧并且右侧的操作有效。有没有人有类似的问题,你是如何解决/修复它?
编辑:我想补充说,这发生在子查询结果为0时,否则我们没有问题,即它的行为如预期。
答
你的查询可以使用子查询分解条款,如被简化:
WITH ns AS (SELECT r.empresa, r.referencia, count(*) as CNT_NUMS_SERIE
FROM ref_numeros_serie n
INNER JOIN emp_referencies r
r.empresa = n.empresa AMD
r.referencia = n.referencia
WHERE n.diposit = 1 AND
NVL(n.actiu, 'N') = 'S'
GROUP BY r.empresa,
r.referencia)
SELECT ref.referencia,
ref.descripcio,
stock_reservat,
stock,
stock_p_rebre,
ns.CNT_NUMS_SERIE
FROM emp_referencies ref
INNER JOIN ref_stk_dip_acu stk
ON stk.empresa = ref.empresa AND
stk.referencia = ref.referencia
INNER JOIN ns
ON ns.empresa = ref.empresa AND
ns.referencia = ref.referencia
WHERE ref.empresa = 1 AND
ref.referencia = '1B' AND
stk.diposit = 1 AND
-- Relevant part
(stk.stock - NVL(stk.stock_reservat, 0)) <> ns.CNT_NUMS_SERIE
-- End of relevant part
GROUP BY ref.empresa,
ref.referencia,
ref.descripcio,
stk.stock,
stk.stock_reservat,
stock,
stock_p_rebre
这可以让你拉共同表达(SELECT COUNT(*)...
)出来,并把它作为一个单独的表。我认为它使查询更容易阅读,并可能节省一些执行时间。
分享和享受。
尝试改变'(stk.stock - stk.stock_reservat)'为'(stk.stock - NVL(stk.stock_reservat,0))'看看是否有帮助。分享并享受。 – 2014-09-01 20:17:17
我们已经尝试过并且没有正常工作 – 2014-09-02 07:09:30
您是否对所有补丁程序进行了更新?我记得10g有问题,正如你所注意到的,11更稳定。 – 2014-09-02 10:57:58