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

rownum 속성

by 롯슈83 2024. 6. 21.
  • select 문으로 조회한 결과에 대하여 차례대로 행 번호를 붙이기 위하여 사용하는 속성이다.
select rownum, eno, ename
from emp e, dept d
where e.dno = d.dno AND dname like '개발%';
-- 박지성 고객이 주문한 도서 이름과 가격을 행번호를 붙여서 출력한다.
-- 조인식을 이용
select rownum,bookname,price from book b, customer c, orders o
where b.BOOKID = o.bookid AND
c.CUSTID = o.CUSTID AND
name = '박지성';

-- 서브 쿼리를 이용
select rownum, bookname,price from book
where bookid in (
    select bookid from orders
    where custid = (
        select custid from CUSTOMER
        where name = '박지성'
    )
);
-- 박지성 고객이 주문한 도서의 이름과 가격을 행번호를 붙여서 출력한다.
-- 단 2권만 출력한다.
select rownum, bookname, price from book
where bookid in (
    select bookid from orders
    where custid = (
        select custid from CUSTOMER
        where name = '박지성'
    )
) and rownum <= 2;

-- 또는 

select rownum,bookname, price from book b, customer c, orders o
where b.BOOKID = o.bookid AND
c.CUSTID = o.CUSTID AND
rownum < 3 and
name = '박지성';
-- 가장 비싼 도서 3권을 출력한다.
select rownum,bookid, bookname, price,publisher --가
from book -- 나
where rownum <= 3 AND 
price is not null   -- 다
order by price desc; --라


-- 확인 작업 => 안되었다는 것을 알 수 있다.
select * from book
where price is not null
order by price desc;

-- 실행 순서 :나 - 다 - 가 - 라 
--이므로 기대하는대로 안나온다. 
-- 따라서 서브 쿼리를 이용해야 한다.
select rownum, b.* from (
    select * from book
    where price is not null
    order by price desc
) b
where rownum <=3;
  • rownum 의 동작은 순서대로 가져오는것은 가능하지만, 중간 것 또는 범위는 가져오지 못한다.
    • 조회한 결과(가상의 테이블)에 행번호인 rownum을 붙여서 앞에서부터 순자적으로 가져오는 것은 잘 된다. 그러나 중간에 있는 일부분을 갖고 오는 것은 불가능하다.
    • 그렇게 하기 위해서는 행번호 붙인 것을 다시 서브 쿼리로 해야한다.
--가격이 높은 순으로 3~5번째 사이의 도서를 출력
select rownum, b.* from (
    select * from book
    where price is not null
    order by price desc
) b
where rownum between 3 and 5;
-- no rows selected.
--3. n의 값으로 조건을 판별
select * from(
    -- 2. 행번호를 붙이고 해당 번호에 애칭 n을 줌
    select rownum n, b.* from (
        -- 1. 정렬함
        select * from book
        where price is not null
        order by price desc
    ) b
) where n between 3 and 5;

 

/*
    개발팀에 근무하는 직책이 사원인 직원들 중에
    실수령액이 가장 높은 직원 2명에 대한
    사원번호, 사원명, 실수령액, 부서번호, 부서명
    관리자명 행번호를 붙여 출력한다.
*/

select  rownum no, b.* from (
    select  eno, ename, (salary+nvl(comm, 0)) 실수령액, dno, 
    (
        select dname from dept d where d.dno =e.dno
    ) 부서명,
    (
        select ename from emp m where e.mgr = m.eno
    ) 관리자명
    from emp e
    where job = '사원' and 
    dno in (
        select dno from dept d2
        where e.dno = d2.dno and dname like '%개발%'
    )
    order by (salary+comm) desc
) b where rownum <= 2;
-- 판매량이 가장 높은 두 권의 도서 정보를 출력하세요.
select * from book where bookname in (
    select bookname from(
        select bookname, count(orderid) 
        from orders o, (
            select * from book b
        ) b
        where o.bookid = b.bookid
        group by bookname
        order by count(*) desc, bookname
    ) where rownum <=2
);
/*
    판매량이 가장 높은 두 권의 도서 정보를 출력하세요.
    판매량 순으로 정렬했을 때 2번째 판매량은 여러권이다.
    2번째 판매량보다 크거나 같은 모든 도서를 
    출력하도록 sql 을 작성해본다.
*/

-- 직접 풀어보기
select b1.*, cnt2 from book b1, (
    select bookid, count(*) cnt2 from orders
    group by bookid
) a
where a.bookid = b1.bookid and
cnt2 in (
    select cnt from (
        select rownum no, bookname, cnt from(
            select bookname, count(orderid) cnt
            from orders o, (
                select * from book b
            ) b
            where o.bookid = b.bookid
            group by bookname
            order by count(*) desc, bookname
        )
    ) where no <= 2
);

-- 답
select * from book
where bookid in (
    select bookid from (
        select bookid, count(*) cnt
        from orders 
        group by bookid 
        order by cnt desc
    ) 
    where cnt >= (
        select cnt from (
            select rownum n, b.* 
            from (
                select bookid, count(*) cnt
                from orders 
                group by bookid 
                order by cnt desc
            ) b
        )
    where n = 2) 
);
-- 확인 코드(책 이름과 판매량 나열)
select bookname, count(orderid) cnt from orders o, book b
where o.bookid = b.bookid
group by bookname
order by cnt desc;
--실수령액이 높은 순으로 하였을 때 5~10번째 직원의 이름을 출력
select ename from(
    select rownum no, b.* from (
        select ename,(salary+comm) s from emp e
        order by (salary+comm) desc
    ) b
) 
where no between 5 and 10
order by no;

 

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

뷰(View)  (0) 2024.06.24
서브쿼리 위치에 따른 용어  (0) 2024.06.21
NULL 처리  (0) 2024.06.21
날짜 시간 함수 -2  (0) 2024.06.21
날짜 시간 함수  (0) 2024.06.20