比较中两列之间的数学运算

时间:2014-09-01 18:40:07

标签: oracle oracle10g

我们正在使用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时会发生这种情况,否则我们就不会遇到问题,即它的行为符合预期。

1 个答案:

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

分享并享受。