我们正在使用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时会发生这种情况,否则我们就不会遇到问题,即它的行为符合预期。
答案 0 :(得分: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(*)...
)并将其视为单独的表。我认为它使查询更容易阅读,并可能节省一些执行时间。
分享并享受。