NVL 질문 드립니다. 0 4 5,965

by sam [SQL Query] NVL NULL [2013.01.28 21:52:41]



안녕하세요.  질문이 생겨서 올립니다..

다름아니라  select 절에서 서브쿼리로 alis A라는 특정값을 가져왔는데요 (결과는 outer join 한거처럼 원하는대로 잘나왔습니다..)

여기서 특정값 A 가 null 인녀석만 가져오려고  쿼리를 바깥에서 감싸서  where 절에서 값을 비교하니깐 제대로 결과를 가져오지 못합니다.. 왜 그런건가요 ?? 대략 쿼리는 아래와 같습니다.

select * from (  
select NVL(select NVL(bb.a, '') as A from bb where aa.a = bb.a )
    from aa
    where exists ( 
select 'A' from c where aa.a = cc.a 
)
)

where A = ''

혹은

 NVL(bb.a, '1') 로하고 
where A = '1'

이렇게 하는데 결과를 못가져옵니다... 안쪽 쿼리를 돌려오면 alias A 컬럼에 제대로 '' 이나  '1' 이 있는데도요... 그래서 다르게 처리해본게

select * from (
  select NVL(select bb.a as A from bb where aa.a = bb.a )
  from aa
  where exists ( select 'A' from c where aa.a = cc.a )
)
where NVL(A, '1') = '1'
 
이렇게 하니 결과는 잘나오는데  plan의 byte수가 10배이상 늘어버렸습니다...

왜 그런건지 이런경우 어떻게 값을 받아와야되는지 알려주시면 감사하겠습니다... ㅜㅜ
by 제로 [2013.01.29 08:44:06]
 
--조건절에서 a 가 null 인 row을 조회하기 위해서는 
--WHERE a IS NULL 로 조회하여야 합니다. =(이퀄) 안됩니다.
select *
from (select (select bb.a from bb where aa.a = bb.a ) as a
   from aa 
   where exists (select 1
          from c 
          where aa.a = cc.a))
where a is null
;      

by 마농 [2013.01.29 08:45:18]

문법이 좀 이상하긴 하지만... 질문을 위해 쿼리를 수정하다가 발생된 오류라고 봅니다.
우선 null 과 '' 은 같습니다. 다시 말하면 '' 은 널입니다. nvl 할 필요가 없는거구요.
널은 일반 값과 달라서 비교 연산이 안됩니다.
a = '' 은 a = null 과 같은 식이며
널과의 비교식은 항상 거짓이므로 조회 안되는게 맞습니다.


그렇다면 왜 1로 바꾸면 byte 가 늘어날까요?
먼저 언급한 바와 같이 a = '' 이 조건은 항상 거짓이므로
이 조건이 있다는 말은 조회할 필요가 없다는 것이므로 테이블을 읽을 필요가 없는거구요.
nvl(a, '1') = '1' 로 바꾸면 조건을 체크해 봐야지만 결과를 알 수 있으므로 테이블을 읽습니다.


미리 nvl 처리를 한 a = '1' 이 안되는 이유는?
올려주신 쿼리가 문법에 맞지 않아 판단하기 힘드네요.
아마도 인라인 뷰안의 쿼리가 결과가 없지 않을까? 생각됩니다.
결과가 없는 것(0 row)과 Null 이라는 결과를 가진것(1 row) 는 다릅니다.
결과가 없는 것을 널을 리턴한걸로 착각한게 아닐까 생각되네요.


by sam [2013.01.29 10:32:42]

마농// 매번 자세한 답변 감사드립니다..^^
조회결과가 없어서 1 나온 항목은 감싸서 해도 안나오는군요...
쿼리 문법틀린거는..죄송합니다..  담부터는  쿼리랑 데이터 같이해서 확인해보고 질문 올리겠습니다...^^


by 마농 [2013.01.29 10:40:46]

스칼라서브쿼리 내부에 결과가 없을 때 스칼라서브쿼리의 결과는 Null
1. SELECT bb.a FROM bb WHERE aa.a = bb.a => 결과 없음 (0 row)
2. SELECT NVL(bb.a, '1') FROM bb WHERE aa.a = bb.a => 결과 없음 (0 row)
3. SELECT (SELECT bb.a FROM bb WHERE aa.a = bb.a) aa FROM aa ==> 결과 (null)
4. SELECT (SELECT NVL(bb.a, '1') FROM bb WHERE aa.a = bb.a) aa FROM aa ==> 결과 (null)
5. SELECT NVL((SELECT bb.a FROM bb WHERE aa.a = bb.a), '1') aa FROM aa ==> 결과 ('1')

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입