본문 바로가기
  • think normal
새로워지기/서른의 생활코딩

삼팔광땡~ MYSQL 입문기 05 - 상관서브쿼리

by 청춘만화 2019. 2. 13.

삼팔광땡~ MYSQL 입문기 05 - 상관서브쿼리 


자, 이제 오~ 다섯 걸음째이다.  무를 고르는 것은 쉽지 않다. 이미 뽑아 놓고 '아니네-' 해봤자 소용없다. 바지주름 소매흙 생각지말고 쪼그려앉아 구석구석 살펴보자 

( 아, 미리 언지를 드리면 실습에 사용되는 테이블은 동일하지만 책에서 설명하고있는 예제와는 똑같지는 않습니다.  >< ) 



0. 이런 실수? 할 수 있다. 

비전공자 또는 낙엽줄로 개발 공부하면서 섭섭하게 느끼는 점이 하나 있다면 너무 당연?한 것은 알려주지 않는다는 것이다. 매번 포스팅을 작성하기 앞서 그런 내용들을 기억나는 데로 적어두려한다. 

1) 아직 생각나는 내용이 없어, 잠시 비워둠~ 니당 ;ㅇ



1. EXISTS - EXISTS 술어를 통해 다른 테이블의 상황을 판단(서브쿼리의 결과가 있고 없음을 판단)하여 UPDATE, SELECT, DELETE로 갱신할 수 있도록 서브쿼리를 사용할 수 있다.

1) 먼저 테스트할 테이블의 초기 상태를 열람해보죠. 아래와 같은 테이블 2개를 통해 이번 실습을 진행하겠습니다.

 select * from sample551; 
 select * from sample552; 



2) EXISTS 술어를 활용하여 데이터가 존재하는지 판별하기 위한 실습입니다. (서브쿼리 조건에 맞는 행이 존재하는 경우 사용)

참고로 교재와 달리 저는 각 테이블에 Alias(s551, s552)를 설정하고 EXISTS 서브쿼리에서 선언한 Alias를 통해 조건을 비교를 했습니다. 물론 Alias를 선언하지않고 '테이블명.컬럼명'= 'sample552.no2' 으로 작성해도 되고요, 책처럼 아무 선언 없이 쓰셔도 됩니다. 저는 개인적으로 습관을 이렇게 들이기위해 Alias를 선언해서 쓰고 있습니다. 데이터베이스가 커지면 컬럼 이름이 중복되는 경우가 발생할 수 있기 때문이죠 ;D 하지만 연습 중이니 각자 편하신데로 고고~ 하세용

코드에 대해 간략히 해석하면,  대략 이 정도? ;D 로 쓸 수 있을 것 같습니다.

업데이트하겠다    

s551에    

설정은    

a컬럼을    '있음'으로

언제냐면 

확인해보고(서브쿼리 조건에 맞는 행이 존재하는 경우)

(선택     모든것을     위치는 

s552에

언제냐면

s552테이블의 no2컬럼과    같으면     s551의 no컬럼이 

);

update 
  sample551 s551
set 
  a='있음' 
where
  exists
     (select * from 
        sample552 s552
      where 
        s552.no2 = s551.no
     );
 select * from sample551; 



2. NOT EXISTS - not을 통해 값을 부정할 수 있다. (서브쿼리 조건에 맞는 행이 존재하지 않는 경우 사용)

update 
  sample551 s551
set 
  a='없음' 
where
  not exists
     (select * from 
        sample552 s552
      where 
        s552.no2 = s551.no
     ); 
 select * from sample551; 




3. 
상관 서브쿼리 - 서브쿼리의 일종으로 EXISTS 술어로 조합시켜서 서브쿼리를 사용하는 방법 익히기

오늘 실습의 첫번째 예제 또한 상관 서브쿼리이다. 부모 명령(update set)이 자식인 서브쿼리(select from where)와 특정한 관계를 맺는 것을 상관 서브쿼리라 부르기 때문이다. 

상관 서브쿼리는 이전 포스팅의 쿼리와 달리, 서브쿼리 부분만 따로 떼어내어 실행시킬 수 없다.

이를테면 update sample551 s551 set a='있음' where exists (select * from sample552 s552 where s552.no2 = s551.no );  에서  뒤에 오는 서브쿼리인 

select * from sample552 where sample552.no2 = sample551.no;

만 떼어서 쓸 수 없다. 아래와 같이 에러가 난다. 상관 서브쿼리에서는 부모 명령과 연관되어 처리되기 때문이라고 한다. 그도 그럴 것이 select를 sample552로 했는데 where 절에서 sample551의 no컬럼을 찾으면 알길이 없기 때문이 아닐까- 



4. IN - 스칼라(1개의 결과끼리 비교할때는 = 연산자를 사용합니다. 다만 집합은 비교할 수 없다고 합니다. 때 집합을 비교할 수 있는 IN을 쓰는거죠.

in 은 집합 안에 포함되어 있으면 참이 됩니다. 반면 not in 으로 지정하면 집합에 포함되어 있지 않을 경우 참이 됩니다. 또한 집계함수와 달리 NULL의 값을 무시하지 않습니다. 다만 비교할 경우엔 = NULL이 아닌, IS NULL로 풀어야 합니다. 다만X2 NOT IN의 경우 양쪽 모두 NULL이 있어도 결N이 됩니다.


1) 그렇다면 앞에서 했던 상관 서브쿼리 예제도 IN을 사용하면 그냥 쿼리로 만들 수도 있겠네요, 한번 해보겠습니다.

update 
  sample551 s551
set 
  a='있음요' 
where
  s551.no in(3,5);
 select * from sample551; 



+ α )   또는, 걍  ' or ' 연산으로도 가능하겠네요,

update 
  sample551 s551
set 
  a='있죠' 
where
  s551.no = 3 or s551.no = 5;
 select * from sample551; 



+ α )   또는, 그래도 실습해본게 있으니 서브쿼리로 바꾸면 아래와 같은 쿼리가 된다. 요렇게 하면 앞에 3번 상관 서브쿼리에서 언급했던 '상관 서브쿼리는 이전 포스팅의 쿼리와 달리, 서브쿼리 부분만 따로 떼어내어 실행시킬 수 없다.'는 이제 남의 얘기?가 되는 것이다.

update 
  sample551 s551
set 
  a='있쑴다' 
where
  s551.no in (select no2 from sample552); 
 select * from sample551; 


오호~ 상관 서브쿼리 끄읏~ ;D 어서 MySQL 끝내고 MARIA DB로 넘어가쟈~ 


댓글