在SQL查询中使用CASE语句的意外结果(oracle DB)

时间:2012-01-18 15:03:33

标签: sql oracle oracle9i

我有这个查询

SELECT  
   CASE WHEN EXISTS (SELECT PARM_VALUE 
                       FROM BO_PARM  
                      WHERE (ENTE_CD = '7316') 
                        AND PARM_CD = 'PAGINAZIONE_PROMOZIONI')  
        THEN p2.PARM_VALUE 
        ELSE p1.PARM_VALUE 
    END as RIGHE 
  FROM
       (SELECT PARM_VALUE 
          FROM BO_PARM  
         WHERE (ENTE_CD = '0000' OR ENTE_CD = 'XXXX') 
           AND PARM_CD = 'PAGINAZIONE_PROMOZIONI') p1,
       (SELECT PARM_VALUE 
          FROM BO_PARM  
         WHERE (ENTE_CD = '7316') 
           AND PARM_CD = 'PAGINAZIONE_PROMOZIONI') p2

基本上我想在第二个查询至少有一行时返回第二个查询的值,否则返回第一个查询的结果。现在这些是返回值:

SELECT PARM_VALUE 
  FROM BO_PARM  
  WHERE (ENTE_CD = '7316') 
    AND PARM_CD = 'PAGINAZIONE_PROMOZIONI' //No retrun

SELECT PARM_VALUE 
  FROM BO_PARM  
 WHERE (ENTE_CD = '0000' OR ENTE_CD = 'XXXX') 
  AND PARM_CD = 'PAGINAZIONE_PROMOZIONI' //returns 10

SELECT  
    CASE WHEN EXISTS (SELECT PARM_VALUE 
                        FROM BO_PARM  
                       WHERE (ENTE_CD = '7316') 
                         AND PARM_CD = 'PAGINAZIONE_PROMOZIONI')  
         THEN p2.PARM_VALUE 
         ELSE p1.PARM_VALUE 
     END as RIGHE 
  FROM
       (SELECT PARM_VALUE 
          FROM BO_PARM  
         WHERE (ENTE_CD = '0000' OR ENTE_CD = 'XXXX') 
           AND PARM_CD = 'PAGINAZIONE_PROMOZIONI') p1,
       (SELECT PARM_VALUE 
          FROM BO_PARM  
         WHERE (ENTE_CD = '7316') 
           AND PARM_CD = 'PAGINAZIONE_PROMOZIONI') p2  //no return, i was expecting 10

我在CASE声明中做错了什么?

2 个答案:

答案 0 :(得分:5)

您现有的查询在两个子查询之间有隐含的笛卡尔联接 - 这意味着当一个查询返回 n 行而另一个返回 m 行时,您将查看返回的总共 m * n 行 - 即。第一组中每行的每个组合以及第二组中的行。

因此,如果在任一集合中返回0行,您将看到总共返回0行。

假设查询都不应该返回多行,那么修改后的查询的最简单版本可能如下:

SELECT coalesce(
       (SELECT PARM_VALUE FROM BO_PARM  WHERE (ENTE_CD = '7316') AND PARM_CD = 'PAGINAZIONE_PROMOZIONI'),
       (SELECT PARM_VALUE FROM BO_PARM  WHERE (ENTE_CD = '0000' OR ENTE_CD = 'XXXX') AND PARM_CD = 'PAGINAZIONE_PROMOZIONI')
                )

答案 1 :(得分:2)

您正在对两个视图执行隐式连接,其中一个视图为空(p1)。

这可能是一种方法:

with a as
(SELECT 
  PARM_VALUE, 
  case when (ENTE_CD = '0000' OR ENTE_CD = 'XXXX') then 1
       when ENTE_CD = '7316' then 2
  end as rnk
FROM BO_PARM  
WHERE PARM_CD = 'PAGINAZIONE_PROMOZIONI' AND  
((ENTE_CD = '0000' OR ENTE_CD = 'XXXX') OR  (ENTE_CD = '7316') )
)
select PARM_VALUE 
from a
where rnk = (select min(rnk) from a)