본문 바로가기
Kosta DevOps 과정 280기/Java

서브쿼리 위치에 따른 용어

by 롯슈83 2024. 6. 21.

select 절 : 스칼라 서브쿼리

  • select 절에 컬럼 이름이 오는 곳에 사용되는 쿼리를 말한다.
  • 단일 행이 오도록 표현해야 한다. 따라서 반드시 조건 식이 필요하다
  • 메인 쿼리와 서브 쿼리의 조건이 항상 필요하므로 상관서브쿼리(서로 상관이 있음을 표현)라고도 부른다.
  • 예제
-- 고객별 고객 아이디, 이름, 총주문 금액 출력
select custid,(
    -- 앞의 custid 와 관련이 있는 name의 단일 행만 가져온다.
    select name from customer c
    where c.custid = o.custid
) name, sum(saleprice)
from orders o
group by custid;
-- 스칼라서브쿼리(= 상관 서브쿼리)를 이용하여
-- 도서명별 판매 건수를 출력한다.
select (
	--  bookid 와 관련이 있는 bookname 의 단일 행만 가져온다.
    select bookname from book b
    where b.bookid = o.bookid
) bookname,count(*) from orders o
group by bookid;
-- 스칼라 서브 쿼리를 이용하여
-- 부서별로 근무자 수, 평균 급여, 최고 급여를 출력한다.
select (
        select dname from dept d2
        where d.dno = d2.dno
    ) 부서명, (
        select count(eno) from emp e
        where d.dno = e.dno
    ) 인원수,
    (
        select avg(nvl(salary, 0)) from emp e
        where d.dno = e.dno
    ) 평균급여,
    (
        select max(nvl(salary, 0)) from emp e
        where d.dno = e.dno
    ) 최고급여
from dept d
group by dno;
  • update 문에도 사용되는 스칼라 서브쿼리
    • updatwe 테이블명 set 컬럼명 = 값 [where ~]
    • updatwe 테이블명 set 컬럼명 = (select ~) [where ~]
    • 예제
-- 실습을 위하여 orders 테이블에 bookname 칼럼을 추가한다.
alter table orders add bookname varchar2(50);

-- update 에 스칼라 서브 쿼리를 이용하여 
-- book 테이블에 있는 책 제목을 orders table
-- 칼럼에 내용을 추가한다.
select * from orders;

update orders o set bookname = (
    select bookname from book b
    where o.bookid = b.bookid
);

select * from orders;

/*
    데이터의 삭제
    - delete 테이블 [where 조건]

    컬럼의 삭제(DDL)
    -- alter table 테이블이름 drop column 컬럼이름

    테이블 삭제(DDL)
    -- drop 테이블명
*/
alter table orders drop column bookname;

 

from 절 : 인라인 뷰(뷰 = 존재하지 않는 가상의 테이블)

  • 서브쿼리가 from 절에 오는 경우를 말한다.
  • 실제로는 존재하지 않는 select 한 결과를 가상의 테이블(View) 이라고 한다.
--실습을 위해 추가
insert into book values(14, '재미있는 자바', 34000, '삼성당');
insert into book values(15, '신나는 자바', 34000, '삼성당');
				
insert into orders values(16,5,14,34000,sysdate);
insert into orders values(17,1,14,34000,sysdate);
insert into orders values(18,2,14,34000,sysdate);
insert into orders values(19,3,14,34000,sysdate);
insert into orders values(20,4,14,34000,sysdate);
insert into orders values(21,1,15,34000,sysdate);
insert into orders values(22,2,15,34000,sysdate);
insert into orders values(23,2,14,34000,sysdate);
insert into orders values(24,2,1,34000,sysdate);
insert into orders values(25,2,2,34000,sysdate);
insert into orders values(26,2,3,34000,sysdate);
insert into orders values(27,3,2,34000,sysdate);
insert into orders values(28,3,15,34000,sysdate);

-- 급여가 가장 낮은 5명의 직원에게 특별상여금을 지급하려고 한다.
--대상자의 사원번호, 사원명, 상여금을 출력한다.
-- 상여금은 급여의 100% 이다
select * from (
    select rownum no, a.* from (
        select eno, ename, salary bonus from emp
        order by salary, comm
    ) a
) where no <= 5;

-- 오늘 날짜에 가장 많이 판매된 도서의 2권의 정보를 출력해봅시다
select * from book
where bookid in (
    select bookid from(   
        select rownum, a.* from 
        (
            select bookid, count(*) cnt 
            from orders
            where to_char(orderdate,'yy/mm/dd') = to_char(sysdate,'yy/mm/dd')
            -- sysdate으로 추가하게 되면 년월일시분초에대한 정보가 함께 추가가된다.
            group by bookid    
            order by cnt desc, bookid desc
        ) a
    ) where rownum <=2
);

 

where 절 : 중첩쿼리(= 중첩 질의)

  • 단일 행 연산자, 다중행 연산자를 구분하여 사용해야 한다.
    • 단일행 연산자 (=, >, <, >=, <=) : 서브 쿼리의 건 수가 한 건(단일 행) 일 때 사용할 수 있다.
    • 다중 행 연산자 (in) : 서브 쿼리의 건수가 여러 건(다중 행)일 때, 사용할 수 있다.
      • >, < , >=, <= 는 any(some) - 아무거나, all- 모두 과 같이 사용해야 한다.
      • 또, 서브쿼리의 건 수가 있는지 없는지만 판단하려면 exist, not exist 를 사용할 수 있다.
-- 평균 주문 금액 이하의 주문번호, 주문 금액 출력
-- 단일 행 연산자 사용
select orderid, saleprice from ORDERS
where saleprice <= 
(select avg(saleprice) avg from orders);
-- 대한민국에 거주하는 고객의 아이디 출력
select custid from customer
where address like '대한민국%';
-- 대한민국에 거주하는 고객의 총 주문 금액을 출력
select sum(saleprice)
from orders
where custid in (
    select custid from customer
    where address like '대한민국%'
);
-- 4번 고객이 주문한 모든 주문 금액보다 더 비싼 도서를
-- 구입한 주문의 주문번호와 금액을 출력하라
select orderid, saleprice from orders
where saleprice > (
    select max(saleprice) from orders
    where custid = 4
);
- '박지성'에게 어떤 도서를 추천 해 주면 좋을까요?
- '박지성'이 구매한 도서와 
	동일한 도서를 가장 많이 구매한 고객 번호 2명을 출력

- '박지성'이 구매한 도서번호를 출력
select bookid from 
orders where custid = (select custid from customer
						where name = '박지성');

    14     1     3     2    15
    
- 고객번호별로 위의 도서를 구매한 건수를 출력   
select custid,count(custid)
from orders 
where bookid in (select bookid from 
orders where custid = (select custid from customer
						where name = '박지성'))  
and custid <> 
(select custid from customer where name = '박지성')
group by custid
order by count(custid) desc;

CUSTID COUNT(CUSTID)
------ -------------
     2             6
     3             3
     5             1


- 위의 결과에 행번호를 붙여서 상위 2개의 고객번호를 출력

select custid 
from ()
where rownum <= 2;

select custid 
from (select custid,count(custid)
from orders 
where bookid in (select bookid from 
orders where custid = (select custid from customer
						where name = '박지성'))  
and custid <> 
(select custid from customer where name = '박지성')
group by custid
order by count(custid) desc)
where rownum <= 2;


CUSTID
------
     2
     3


- 위의 고객들이 주문한 도서번호를 출력

select bookid 
from orders 
where custid in ();


select distinct bookid 
from orders 
where custid in (select custid 
from (select custid,count(custid)
from orders 
where bookid in (select bookid from 
orders where custid = (select custid from customer
						where name = '박지성'))  
and custid <> 
(select custid from customer where name = '박지성')
group by custid
order by count(custid) desc)
where rownum <= 2);


    14     5    6    10     8    15     1     2     3

- 위의 결과에서 박지성이 구매한 도서목록를 빼 줍니다.
()
minus
()
    
(select distinct bookid 
from orders 
where custid in (select custid 
from (select custid,count(custid)
from orders 
where bookid in (select bookid from 
orders where custid = (select custid from customer
						where name = '박지성'))  
and custid <> 
(select custid from customer where name = '박지성')
group by custid
order by count(custid) desc)
where rownum <= 2))
minus
(select bookid from 
orders where custid = (select custid from customer
						where name = '박지성'));


==> 도서번호가 위의 결과에 해당하는 도서정보를 출력
select * from 
book
where bookid in ();


select * from 
book
where bookid in ((select distinct bookid 
from orders 
where custid in (select custid 
from (select custid,count(custid)
from orders 
where bookid in (select bookid from 
orders where custid = (select custid from customer
						where name = '박지성'))  
and custid <> 
(select custid from customer where name = '박지성')
group by custid
order by count(custid) desc)
where rownum <= 2))
minus
(select bookid from 
orders where custid = (select custid from customer
						where name = '박지성')));



select * from 
book
where bookid in ((select distinct bookid 
from orders 
where custid in (select custid 
from (select custid,count(custid)
from orders 
where bookid in (select bookid from 
orders where custid = (select custid from customer
						where name = '임유나'))  
and custid <> 
(select custid from customer where name = '임유나')
group by custid
order by count(custid) desc)
where rownum <= 2))
minus
(select bookid from 
orders where custid = (select custid from customer
						where name = '임유나')));

	
SQL> select * from
  2  book
  3  where bookid in ((select distinct bookid
  4  from orders
  5  where custid in (select custid
  6  from (select custid,count(custid)
  7  from orders
  8  where bookid in (select bookid from
  9  orders where custid = (select custid from customer
 10  where name = '임유나'))
 11  and custid <>
 12  (select custid from customer where name = '임유나')
 13  group by custid
 14  order by count(custid) desc)
 15  where rownum <= 2))
 16  minus
 17  (select bookid from
 18  orders where custid = (select custid from customer
 19  where name = '임유나')));

선택된 레코드가 없습니다.
==> 구매이력이 없는 사람은 추천도서가 없어요!

 

'Kosta DevOps 과정 280기 > Java' 카테고리의 다른 글

index  (0) 2024.06.24
뷰(View)  (0) 2024.06.24
rownum 속성  (0) 2024.06.21
NULL 처리  (0) 2024.06.21
날짜 시간 함수 -2  (0) 2024.06.21