数学运算

数学运算

问题描述:

我们正在使用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

尝试改变'(stk.stock - stk.stock_reservat)'为'(stk.stock - NVL(stk.stock_reservat,0))'看看是否有帮助。分享并享受。 – 2014-09-01 20:17:17

+0

我们已经尝试过并且没有正常工作 – 2014-09-02 07:09:30

+0

您是否对所有补丁程序进行了更新?我记得10g有问题,正如你所注意到的,11更稳定。 – 2014-09-02 10:57:58

你的查询可以使用子查询分解条款,如被简化:

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(*)...)出来,并把它作为一个单独的表。我认为它使查询更容易阅读,并可能节省一些执行时间。

分享和享受。