subquery 활용

혜쿰·2023년 7월 27일
0

query문은 동일한 결과를 얻는데 있어 여러 방법을 사용할 수 있다. 다음 예제를 통해 알아보자.

  • 총무부 소속 직원들이 관리하는 고객 자료 출력
  • join 풀이
 SELECT gogek_no, gogek_name,gogek_tel FROM gogek
INNER JOIN jikwon ON jikwon_no = gogek_damsano 
INNER JOIN buser ON buser_no = buser_num
WHERE buser_name = '총무부';
  • subquery 풀이
 SELECT gogek_no, gogek_name,gogek_tel FROM gogek
WHERE gogek_damsano IN (SELECT jikwon_no FROM jikwon WHERE buser_num=(SELECT buser_no FROM buser WHERE buser_name = '총무부'));

from 절에 subquery 적용

  • 전체 평균 연봉과 최대 연봉 사이의 연봉을 받는 직원은?

SELECT jikwon_no, jikwon_name, jikwon_pay FROM jikwon a, (SELECT AVG(jikwon_pay) avgs, 
MAX(jikwon_pay) maxs FROM jikon 
WHERE a.jikwon_pay BETWEEN b.avgs AND b.maxs;
  • 각 부서별로 최고 연봉을 버는 직원 출력
SELECT a.jikwon_no, a.jikwon_name, a.jikwon_pay FROM jikwon a,
(SELECT buser_num, MAX(jikwon_pay) maxpay FROM jikwon GROUP BY buser_num) b  
WHERE a.buser_num = b.buser_num AND a.jikwon_pay = b.maxpay;

group by의 having 절에 subquery

  • 부서별 평균 연봉 중 30번 부서의 평균 연봉보다 더 많은 연봉 수령 부서는?
SELECT buser_num, AVG(jikwon_pay) FROM jikwon 
GROUP BY buser_num
HAVING AVG(jikwon_pay) > (SELECT AVG(jikwon_pay) FROM jikwon WHERE buser_num = 30);

exists 연산자

  • exists 연산자 : true or false 반환

  • 직원이 있는 부서 자료 출력

SELECT buser_name, buser_loc FROM buser bu 
WHERE EXISTS (SELECT 'imsi' FROM jikwon WHERE buser_num = bu.buser_no);
  • 직원이 없는 부서 자료 출력
SELECT buser_name, buser_loc FROM buser bu 
WHERE not EXISTS (SELECT 'imsi' FROM jikwon WHERE buser_num = bu.buser_no);

상관 subquery

  • 상관 subquery : 안쪽 질의에서 바깥쪽 질의를 참조하고 다시 안쪽의 질의 결과를 바깥쪽 질의에서 참조하는 형태 / 가독성이 떨어짐

  • 각 부서별로 최고 연봉을 버는 직원 출력

SELECT * from jikwon a 
WHERE a.jikwon_pay=(SELECT MAX(b.jikwon_pay) FROM jikwon b
WHERE a.buser_num=b.buser_num); 
  • 연봉 순위 3위 이내의 자료 출력 (내림차순)
SELECT a.jikwon_no, a.jikwon_name, a.jikwon_pay FROM jikwon a
WHERE 3 > (SELECT COUNT(*) FROM jikwon b WHERE b.jikwon_pay > a.jikwon_pay) 
AND jikwon_pay IS NOT null
ORDER BY jikwon_pay DESC;

subquery를 table 생성 및 insert에서 수행

CREATE TABLE imsi1 AS SELECT * FROM jikwon; -- pk 및 사용자 제약조건을 제외한 복사본이 생성
DESC imsi1;
DESC jikwon;
SELECT * FROM imsi1;

CREATE TABLE imsi2 AS SELECT * FROM jikwon WHERE 1 = 0; -- 조건을 말도 안되는 조건을 달기
DESC imsi2;
SELECT * FROM imsi2; -- 데이터없이 구조만 생성
INSERT INTO imsi2 SELECT * FROM jikwon WHERE jikwon_rating = 'a'; -- 서브쿼리의 일종
INSERT INTO imsi2 (jikwon_no, jikwon_name, buser_num) SELECT jikwon_no, jikwon_name, buser_num
FROM jikwon WHERE jikwon_rating = 'b';
select * FROM imsi2;
CREATE TABLE imsi3 as select jikwon_no bunho, jikwon_name irum, jikwon_pay pay 
FROM jikwon  WHERE 1 = 0; -- 일부 칼럼만 이름 바꿔서 생성 / 구조만 생성
DESC imsi3;
SELECT * FROM imsi3;

-- update에서 subquery 사용
UPDATE imsi1 SET jikwon_jik = (SELECT jikwon_jik FROM jikwon WHERE jikwon_name = '한송이')
WHERE jikwon_no = 1;
SELECT * FROM imsi1;

-- delete에서 subquery 사용
DELETE FROM imsi1 WHERE jikwon_no IN (SELECT DISTINCT gogek_damsano FROM gogek);
SELECT * FROM imsi1;

0개의 댓글