์ƒˆ์†Œ์‹

IT & Security/DB

[Oracle DB] ์ง‘๊ณ„ํ•จ์ˆ˜ | Join

  • -
๋ฐ˜์‘ํ˜•

์ง‘๊ณ„ํ•จ์ˆ˜๋ž€? 

์—ฌ๋Ÿฌ ํ–‰ ๋˜๋Š” ํ…Œ์ด๋ธ” ์ „์ฒด ํ–‰์œผ๋กœ๋ถ€ํ„ฐ ํ•˜๋‚˜์˜ ๊ฒฐ๊ด๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.


  • COUNT : ๊ฒ€์ƒ‰๋œ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์œ ์ผํ•œ๊ฒŒ *์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • MAX : ์ปฌ๋Ÿผ ๊ฐ’ ์ค‘์—์„œ ์ตœ๋Œ€๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • MIN : ์ปฌ๋Ÿผ ๊ฐ’ ์ค‘์—์„œ ์ตœ์†Œ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • SUM : ๊ฒ€์ƒ‰๋œ ์ปฌ๋Ÿผ์˜ ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ๋ฌธ์ž์˜ ํ•ฉ์„ ๊ตฌํ•  ์ˆ˜๋Š” ์—†๋‹ค.

MAX์™€ MINํ•จ์ˆ˜์—์„œ๋Š” ๋ฌธ์ž์—์„œ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Why???!!! ์•„์Šคํ‚ค์ฝ”๋“œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


 SUM ํ•จ์ˆ˜ 


๋‹จ์ผํ–‰ ํ•จ์ˆ˜ : null์ด ํ•˜๋‚˜๋ผ๋„ ์žˆ์œผ๋ฉด ๊ฒฐ๊ณผ๊ฐ’์ด ๋‹ค null์ด ๋œ๋‹ค.

์—ฌ๋Ÿฌํ–‰ ํ•จ์ˆ˜ : ํ–‰ ์ง‘ํ•ฉ๋‹น ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ, null๊ฐ’์ด ์žˆ์œผ๋ฉด ์ œ์™ธ๋˜์–ด ๊ฒฐ๊ณผ๊ฐ’์ด ์ถœ๋ ฅ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ์•„๋ž˜๋Š” ์—ฌ๋Ÿฌํ–‰ ํ•จ์ˆ˜์ด๋ฏ€๋กœ, NULL๊ฐ’์ด ์ œ์™ธ๋˜์–ด ๊ฒฐ๊ณผ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

select sum(sal),sum(comm)
from emp;


 COUNT ํ•จ์ˆ˜ & MIN ํ•จ์ˆ˜ 

์œ„์—์„œ ๋งํ–ˆ๋“ฏ์ด, MINํ•จ์ˆ˜๋Š” ๋ฌธ์ž๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ, ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

select count(*), count(comm), min(ename), min(sal)
from emp;
-- ์ง‘๊ณ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ


 ์ค‘๋ณต ์ œ๊ฑฐ ( distinct ) 

distinct๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ค‘๋ณต์„ ์ œ๊ฑฐํ•˜์—ฌ, ์ถœ๋ ฅํ•ด์ค€๋‹ค.

select distinct job from emp;


 ์กฐ์ธ ( join ) 

1. ๊ต์ฐจ์กฐ์ธ ( cross join )

2. ๋‚ด๋ถ€์กฐ์ธ ( inner join ) :  theta [non-]equi,natural

3. ์™ธ๋ถ€์กฐ์ธ( outer join ) : [ left | right | full ] [outer] join

4. ์…€ํ”„์กฐ์ธ( self join )


 ์˜ˆ์ œ 

์•„๋ž˜ ์„ค๊ณ„ํ‘œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ, ์ง„ํ–‰๋œ ์˜ˆ์ œ์ด๋‹ค.


 1. ์šฐ๋ฆฌ ํšŒ์‚ฌ์— ๋ถ€์„œ๊ฐ€ ๋ช‡๊ฐœ์•ผ?? 

select count(deptno) from dept;

์œ„ ์†Œ์Šค์—์„œ deptno ๋Œ€์‹  *์„ ์“ฐ๋ฉด, ์ „์ฒด๋ฅผ ์ถœ๋ ฅํ•ด์ค€๋‹ค.


 2. ์‚ฌ์›์ด ํ˜„์žฌ ์†Œ์†๋˜์–ด ์žˆ๋Š” ๋ถ€์„œ๋Š” ๋ช‡๊ฐœ์•ผ?? 

select count(distinct deptno) from emp;


 3. ๋ถ€์„œ๋ณ„๋กœ ์‚ฌ์›์˜ sal์ด ๋‚ฎ์€ ์ˆœ์œผ๋กœ deptno,dname,empno,ename,sal์„ ์ถœ๋ ฅํ•ด๋ผ. 

select b.deptno,b.dname,a.empno,a.ename,a.sal 
from emp a join dept b 
on a.deptno=b.deptno order by 1,5 asc;

empํ…Œ์ด๋ธ”์˜ ๋ณ„์นญ์„ a, dept๋Š” b๋กœ ์นญํ•˜์˜€๋‹ค. 

์ฐธ๊ณ ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ์€ asc, ๋‚ด๋ฆผ์ฐจ์ˆœ์€ desc์ด๋ฉฐ, default๋Š” asc์ด๋‹ค.


 4. ๋ถ€์„œ๋ณ„ ์‚ฌ์›์ด ๋ช‡๋ช…์ธ์ง€ deptno,dname๋ถ€์„œ๋ณ„ ์ธ์›์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ด๋ผ. 

select a.deptno, b.dname, count(*) as "๋ถ€์„œ๋ณ„ ์ธ์› ์ˆ˜" 
from emp a join dept b on a.deptno=b.deptno group by a.deptno, b.dname; 
--์‚ฌ๋žŒ์˜ ์ˆ˜๋ฅผ ๋ฝ‘์„ ๋•Œ๋Š” empํ…Œ์ด๋ธ”์—์„œ ๋ฝ‘์•„์•ผํ•จ


 4-1. ๋ถ€์„œ๋ณ„ ์‚ฌ์›์ด ๋ช‡๋ช…์ธ์ง€ depno,dname,๋ถ€์„œ๋ณ„ ์ธ์› ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋˜,  5๋ช… ์ด์ƒ์ธ ๋ถ€์„œ๋งŒ ๋ถ€์„œ๋ณ„ ์ธ์›์ˆ˜ ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ. 

select a.deptno, b.dname, count(*) as "๋ถ€์„œ๋ณ„ ์ธ์› ์ˆ˜" 
from emp a join dept b on a.deptno=b.deptno 
group by a.deptno, b.dname 
having count(*) >= 5
order by 3 desc; 

 


 4-2. ๋ถ€์„œ๋ณ„ ์‚ฌ์›์ด ๋ช‡๋ช…์ธ์ง€ 30๋ฒˆ ์ด์ƒ์ธ ๋ถ€์„œ๋ฒˆํ˜ธ๋งŒ์œผ๋กœ ๋ถ€์„œ๋ณ„ ์ธ์›์ˆ˜ ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ. 

select a.deptno, b.dname, count(*) as "๋ถ€์„œ๋ณ„ ์ธ์› ์ˆ˜" 
from emp a join dept b on a.deptno=b.deptno 
where a.deptno >= 30
group by a.deptno, b.dname 
having count(*) >= 5
order by 3 desc; 

์•„๋ž˜ ์ฝ”๋“œ๋„ ์œ„์™€ ๊ฐ™์€ ์˜๋ฏธ์ด๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด, where์ ˆ์— ์žˆ๋Š” ๊ฒƒ์„ having์— ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.

select a.deptno, b.dname, count(*) as "๋ถ€์„œ๋ณ„ ์ธ์› ์ˆ˜" 
from emp a join dept b on a.deptno=b.deptno 
--where a.deptno >= 30
group by a.deptno, b.dname 
having a.deptno >= 30 and count(*) >= 5
order by 3 desc; 

 
  โ€ป ์ฐธ๊ณ 
  
  ์–ด๋– ํ•œ ๊ฐ’์„ ์ถœ๋ ฅํ•  ๋•Œ, ๊ธฐ๋ณธ์ ์ธ ํ˜•์‹์™€ ๊ฐ™๋‹ค.

  select ~from
  where ( where์€ ๊ฐœ๋ณ„์ ์ธ ์กฐ๊ฑด๋งŒ ์จ์•ผ๋จ )
  group by ~~~~
  having (๊ทธ๋ฃน์— ๋Œ€ํ•œ ์กฐ๊ฑด)
  order by ;

  ์—ฌ๊ธฐ์„œ where์ ˆ๊ณผ having์— ๋Œ€ํ•œ ์ฐจ์ด์ ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž.
  where์ ˆ์—์„œ๋Š” ๊ฐœ๋ณ„์ ์ธ ์กฐ๊ฑด๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ, having์—์„œ๋Š” ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ์ž‘์„ฑํ•œ๋‹ค.


 4-4. ๋ถ€์„œ๋ณ„ ์‚ฌ์›์ด ๋ช‡๋ช…์ธ์ง€ job์ด 'President'์ธ ์‚ฌ์›์„ ์ œ์™ธํ•˜๊ณ  deptno, dname, ๋ถ€์„œ๋ณ„ ์ธ์›์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋˜ 5๋ช…์ด์ƒ์ธ ๋ถ€์„œ๋งŒ ๋ถ€์„œ๋ณ„ ์ธ์›์ˆ˜ ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ. 

์ง‘๊ณ„ํ•จ์ˆ˜์™€ ๊ฐ™์ด ์“ฐ๋Š” select list์— ์žˆ๋Š” ๋‚˜๋จธ์ง€ ์ปฌ๋Ÿผ์€ ๋ฐ˜๋“œ์‹œ group by์— ์™€์•ผ ํ•œ๋‹ค.

์˜ค๋ผํด์—์„œ ๊ฐ™์ง€ ์•Š๋‹ค๋Š” ์˜๋ฏธ์˜ ๊ธฐํ˜ธ๋Š” != ๋„ ๋˜๊ณ , <> ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

select a.deptno, b.dname, count(*) as "๋ถ€์„œ๋ณ„ ์ธ์› ์ˆ˜" 
from emp a join dept b on a.deptno=b.deptno 
where job != 'PRESIDENT'
group by a.deptno, b.dname
having count(*)>=5
order by 3 desc;

ํ•ด๋‹น ๋ฌธ์ œ์—์„œ๋Š” ๋ถ€์„œ๋ณ„๋กœ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, where์กฐ๊ฑด๋ฌธ์„ having์— ๋„ฃ์œผ๋ฉด ์•ˆ๋œ๋‹ค. 


 5. ๋ถ€์„œ๋ณ„๋กœ ๊ฐ job๋ณ„ ์ธ์›์ด ๋ช‡๋ช…์ธ์ง€๋ฅผ deptno, dname, job, ์ธ์›์ˆ˜๋ฅผ ๋ถ€์„œ๋ณ„ job๋ณ„๋กœ ์ •๋ ฌํ•˜์—ฌ ์ถœ๋ ฅํ•ด๋ผ. 

select b.deptno,a.dname,b.job, count(*) as "์ธ์›์ˆ˜" 
from dept a join emp b on a.deptno=b.deptno
group by b.job, b.deptno, a.dname
order by 1,3;


 6. ์•„๋ž˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด, ์ถœ๋ ฅํ•ด๋ผ. 

select deptno, count(decode(job,'CLERK',0)) as CLERK, 
                count(decode(job,'MANAGER',0)) as MANAGER,
                count(decode(job,'PRESIDENT',0)) as PRESIDENT,
                count(decode(job,'ANALYST',0)) as ANALYST,
                count(decode(job,'SALESMAN',0)) as SALESMAN
from emp group by deptno order by 1;

 7. emp์˜ sal์ด salgrade์˜ ์–ด๋–ค grade์— ํ•ด๋‹น๋˜๋Š”์ง€ ename, job, sal, grade๋ฅผ job๋ณ„๋กœ sal ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ. 

select e.ename, e.job, e.sal, s.grade 
from emp e join salgrade s 
    on e.sal>=s.losal and e.sal<=hisal 
order by 2,3 desc;

์œ„ ์กฐ๊ฑด๋ฌธ์„ between์œผ๋กœ ๋ฐ”๊ฟ” ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

select e.ename, e.job, e.sal, s.grade 
from emp e join salgrade s 
    --on e.sal>=s.losal and e.sal<=hisal 
    on e.sal between s.losal and s.hisal
order by 2,3 desc;


 7-1. emp์˜ sal์ด salgrade์˜ ์–ด๋–ค grade์— ํ•ด๋‹น๋˜๋Š”์ง€ ename, job, sal, grade, deptno, dname์„ job๋ณ„๋กœ  sal ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅ 

 ์ด์ค‘ join์— ๋Œ€ํ•œ ๋ฌธ์ œ๋กœ, ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

select e.ename, e.job, e.sal, s.grade,d.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno 
           join salgrade s on e.sal between s.losal and s.hisal
order by 2,3 desc;

์•„๋ž˜๋Š” ์œ„์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ์˜ ์˜๋ฏธ๋กœ, join์˜ ์œ„์น˜๋งŒ ๋ฐ”๊ฟ”์„œ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋‹ค.

select e.ename, e.job, e.sal, s.grade,d.deptno, d.dname
from salgrade s join emp e on e.sal between s.losal and s.hisal
        	join dept d on e.deptno=d.deptno     
order by 2,3 desc;

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ inner ์กฐ์ธ์— ๋Œ€ํ•œ ์˜ˆ์ œ์ด๋‹ค. 


์—ฌ๊ธฐ์„œ ๋ถ€ํ„ฐ๋Š” outer์กฐ์ธ์— ๋Œ€ํ•œ ์˜ˆ์ œ์ด๋‹ค.

 7-2. ๋ชจ๋“  ๋ถ€์„œ์— ๋Œ€ํ•˜์—ฌ emp์˜ sal์ด salgrade์˜ ์–ด๋–ค grade์— ํ•ด๋‹น๋˜๋Š”์ง€deptno,dname,ename,job,sal,grade์„ ๋ถ€์„œ๋ณ„๋กœ job๋ณ„๋กœ sal ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ.

select d.deptno, d.dname, e.ename, e.job, e.sal, s.grade
from emp e right outer join dept d on e.deptno=d.deptno 
            left outer join salgrade s on e.sal between s.losal and s.hisal
order by 1,4,5 desc;

์•„๋ž˜๋Š” left, right, full์˜ join์— ๋Œ€ํ•œ ์‚ฌ์ง„์ด๋‹ค.

์ดํ•ดํ•˜๋Š”๋ฐ, ์ข‹์€ ์‚ฌ์ง„์ด๋ผ์„œ ๊ฐ€์ ธ์™”๋‹ค.^_^

์ฐธ๊ณ  ์ฃผ์†Œ : https://haenny.tistory.com/34


7-3. ๋ชจ๋“  ๋ถ€์„œ์— ๋Œ€ํ•˜์—ฌ emp์˜ sal์ด salgrade์˜ ์–ด๋–ค grade์— ํ•ด๋‹น๋˜๋Š”์ง€ deptno,dname,ename,job,sal,grade์„ ๋ถ€์„œ๋ณ„๋กœ job๋ณ„๋กœ sal ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ.(๋‹จ, sal emp dept์ˆœ์œผ๋กœ ์กฐ์ธ)

select d.deptno, d.dname, e.ename, e.job, e.sal, s.grade
from salgrade s 
        join emp e on e.sal between s.losal and s.hisal
        right join dept d on e.deptno=d.deptno     
order by 1,4,5 desc;

8. ๋ชจ๋“  ๋ถ€์„œ์— ๋Œ€ํ•˜์—ฌ sal์˜ ํ•ฉ๊ณ„๊ฐ€ 1000000์ด์ƒ์ด๋ฉด 'good' , 5000์ด์ƒ์ด๋ฉด 'average' , 1์ด์ƒ 5000๋ฏธ๋งŒ์ด๋ฉด 'bad' ,  0์ด๋ฉด 'nopay' , ์—†์œผ๋ฉด 'not exists'๋กœ ํ‰๊ฐ€ํ•˜๋˜ deptno,dname, ๋ถ€์„œ๋ณ„ sal์˜ ํ•ฉ๊ณ„, ํ‰๊ฐ€๋ฅผ ์ถœ๋ ฅํ•ด๋ผ.

select d.deptno,d.dname, sum(e.sal) as "sal ํ•ฉ๊ณ„",
    case 
    when sum(e.sal)>= 1000000 then 'good'
    when sum(e.sal)>= 5000 then 'average'
    when sum(e.sal) between 1 and 5000 then 'bad'
    when sum(e.sal) = 0 then 'no pay'
    when sum(e.sal) is null then 'not exists'
    end as ํ‰๊ฐ€
from dept d left outer join emp e on e.deptno=d.deptno
group by d.deptno,d.dname
order by 1;


9. ๋ชจ๋“  ๋ถ€์„œ์— ๋Œ€ํ•˜์—ฌ emp์˜ sal+sal*comm์ด salgrade์˜ ์–ด๋–ค grade์— ํ•ด๋‹น๋˜๋Š”์ง€ deptno, dname, ename, job, sal, sal+sal*comm, grade๋ฅผ ์ถœ๋ ฅํ•˜๋˜, ์—†๋Š” grade๋Š” '***'๋กœ ํ‘œ์‹œํ•˜๊ณ  ๋ถ€์„œ๋ณ„๋กœ job๋ณ„๋กœ sal ์ด ๋†’์€ ์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ. 

select d.deptno,d.dname,e.ename,
    e.job,e.sal,e.sal+e.sal*nvl(e.comm,0)as ํ•ฉ,nvl(to_char(s.grade),'****') as ๋“ฑ๊ธ‰
from dept d left outer join emp e on d.deptno = e.deptno
    left outer join salgrade s on e.sal+e.sal*nvl(e.comm,0) between s.losal and s.hisal
    order by 1,4 desc;


์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ๋Š” ๊ต์ฐจ์กฐ์ธ์ด๋‹ค.

 

์•„๋ž˜๋Š” ๋ฐ”๋กœ ์œ„์˜ ex3๊ณผ ๊ฐ™์€ ์˜ˆ์ œ์ด๋‹ค.

select b.deptno,b.dname,a.empno,a.ename,a.sal from emp a, dept b 

๊ฒฐ๊ณผ๊ฐ’์ด ๋„ˆ๋ฌด ๊ธธ์–ด, ์ผ๋ถ€๋งŒ ์บก์ณํ•œ ๊ฒฐ๊ณผ์ด๋‹ค.

์ด์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ์กฐ๊ฑด์„ ์•ˆ ์ฃผ๋ฉด, ๋ฌด์ž‘์œ„ ์กฐ์ธ์ด ๋˜์–ด๋ฒ„๋ฆฐ๋‹ค๋Š” ๋ฌธ์ œ์ ์„ ์•Œ์•„๋‘์ž.

 

 

 

 

๋ฐ˜์‘ํ˜•
Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.