Неожиданный результат при использовании оператора CASE в SQL-запросе (oracle DB) - PullRequest
1 голос
/ 18 января 2012

у меня есть этот запрос

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 ]

5 голосов
/ 18 января 2012

Ваш существующий запрос имеет подразумеваемое декартово соединение между двумя подзапросами - это означает, что когда один запрос возвращает 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')
                )
2 голосов
/ 18 января 2012

Вы делаете неявное соединение двух представлений, причем одно из них пустое (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)
...