서브쿼리 및 관계형 테이블

두부링·2024년 11월 26일

sql

목록 보기
4/5
post-thumbnail

1. <oracle 에서 조인을 바라보는 관점>

오라클의 기본 설정은 모든 행를 조인을 수행한 것중에서 내가 원하는 행만 남기기(where)
조건을 안 주면 테이블의 행을 모두 연결함

  • ANSI 표준: 연결 조건과 일반 조건 분리 가능함
  • 오라클에서 디폴트는 생략 가능

2. <조인 조건 간략하게>

  • USING( ) : 사용하면 . 사용 금지, **조건에서 같은 열을 작성할 때

3. <서브쿼리>

  • select의 결과도 하나의 테이j블처럼 보기
  1. 단일행
    • slaes 부서에 근무하는 사원의 사원번호, 이름, 직업을 출력
  2. 다중행
    • 직책이 CLERK과 동일한 급여를 받는 사원의 번호, 이름, 급여를 출력
  3. 상관 서브쿼리 : 그냥 관계가 있다...
  4. from절 안에 select의 결과가 올 수 있음
    • 부서별 평균 급여

3-1.<서브쿼리의 예제문제>

  • 운동장...
  • 사원의 급여로 내림차순 정렬해서
  • 위에서부터 5명씩 짤랐을 때 2번째 그룹의
  • 사원번호, 사원이름, 급여를 출력해 보세요.
    => 예시) 블로그의 페이지 방문시 1페이지, 2페이지...= 페이지 처리
    => 정렬 - 순번 - select 그러면 그룹을 만들 필요가 없음
    => rownum은 무조건 별칭
select *
from
	(select sub.*,rownum sunbun
	from
		(select empno,ename,sal
		from emp 
		order by sal desc) sub)
where sunbun between 6 and 10

-> select 안에 select
-> table 생성 후 선택, 생성 후 선택

3-2.서브쿼리 정호T 기출문제(10문제)

  1. 급여가(sal)가 3000 이상인 직원의 이름과 급여를 조회하시오.
select ename,sal
from emp
where sal>=3000;
  1. 매니저(mgr)가 null인 직원의 이름을 조회하기
select ename
from emp
where mgr is null;
  1. 커미션이 null이 아닌 직원의 이름과 커미션을 조회하기
select ename,comm
from emp
where comm is not null;
  1. 이름이 'A'로 시작하는 직원의 이름과 직책 구하기
select ename,job
from emp
where ename like 'A%;

5. 부서 번호가 20인 직원 중 급여가 가장 높은 직원의 이름과 급여를 조회하기

select ename,sal
from emp
where deptno = 20 and sal=(select max(sal) from emp where deptno=20) ;
  • 5번 where절에서는 집계 함수 사용이 불가함
select ename,sal 
from emp 
where deptno=20 and sal=max(sal)
-- where절에서는 max 사용불가
  • where는 행을 필터링하는 조건으로 사용됨
  • 집계함수는 where 전에 실행되지 않음
  1. 각 부서의 직원 수를 조회하기
select deptno, count(*) from emp
group by(deptno);

7.급여의 합계가 5000이상인 부서의 부서 번호와 급여 합계를 조회하기

select deptno,sum(sal)
from emp
group by(deptno)
having sum(sal)>=5000;

8.부서별 최고 급여를 받는 직원의 이름과 급여를 조회하기

select deptno,ename,sal
  from emp
  where (deptno,sal) in (select deptno,max(sal) from emp group by deptno);

=> 칼럼 2개 비교 가능함

<나의 오답>

select ename,sal
from emp
where sal in (select max(sal) from emp group by deptno);

왜 안되는가? sal만 비교하기에 각 부서의 최대값이 안 나올수도 있음

만약 20번 부서에서 sal이 2850이 있다면 조회되어 각 부서의 최대값이 안 나옴

9.급여가 부서별 평균 급여보다 높은 직원의 이름, 급여 조회하기

select ename,sal
from emp e1
where sal >any(select avg(sal) from emp where deptno= e1.deptno );

  • 서브쿼리에서 밖에 있는 테이블의 데이터가 필요할 수도 있음
  • 서브쿼리의 결과는 deptno에 따라서 평균이 달라짐

<나의 오답>

 select ename,sal
 from emp
 where sal >any (select avg(sal) from emp group by(deptno));

10. 모든 직원의 급여와 평균 급여의 차이를 계산하시오

select ename,sal, sal -(select avg(sal) from emp) diff
from emp;

4. 관계형 데이터베이스

  • 관계를 설정하는 목적?
    잘못된 데이터가 들어가지 않도록 방지
    부모 자식 관계에 따라서 데이터를 넣을 수도 안될수도
    => 테이블들 간의 관계
    왜래키, 제약조건,....

4-1. 제약조건

  • 제약조건의 이름은 꼭 설정 - 아니면 컴퓨터에서 알아보기 힘들게 설정함
  • check : 조건이 true일때만 row가 만들어진다

PRIMARY KEY 제약조건에 위배 되는 경우

NOT NULL, CHECK 제약조건 위배

COLUMN LEVEL 제약 조건 부여

TABLE LEVEL 제약 조건 부여 ( NOT NULL 은 COLUMN LEVEL 만 가능)

제약조건 추가

emp2 테이블에 제약조건 추가

제약 조건 변경 시 alter : 제약 조건을 넣는다는 것은 아예 바꾸는 거임

4-2. 관계가 있는 테이블 생성

  • 칼럼 옆에 선언하는 제약 조건을 칼럼수준에서 정의 했다라고 말함 = column level 제약 조건

  • 테이블를 정의 할때 선언하는 제약조건은 = table level 제약 조건 -> 칼럼명이 들어가야 함
    not null은 테이블 수준에서 정의할 수 없음

  • 개발할 때는 제약 조건 없이 만든 후에 조건을 넣음

5. <정호 T 과제>

  1. dept2 테이블과 emp2 테이블을 여러번 만들고 삭제하고를 반복해 보세요
    (제약 조건 적절히 부여하기)

  2. 만들어진 테이블에 row를 제약조건을 위배하지 않고 추가 해보세요.

  3. 제약조건을 위배하는 다양한 테스트를 해 보세요.

부모 - 자식 간의 관계가 이어져 있으면 자식을 먼저 삭제하고 부모를 삭제해야 함

<질문>

  • 다중행은 any, all로 값을 하나하나 모두 비교함

<놓친 파트 & 어려운>

자신의 직속 상관이 'KING' 인 사원의 이름과 급여를 출력해 보세요.
**서브쿼리랑 join으로 둘다 풀기

(일단 먼저 테이블 만들고 where 조건 생각하기)
select e1.ename,e1.sal,e2.ename manager_name
from emp e1
join emp e2 on e1.mgr=e2.empno
where e2.ename='KING'

단일행, 다중행 서브쿼리 예제문제,,,,

  • 뭐를 비교하고 있는가?
  • max sal은 하나니 단순 연산자로 비교가 가능함

ALL , ANY

  • row가 여러개 => 비교하려면 다중행 연산자(all, any)가 필요함
    all: 모두 any: 어느 하나라도
  • 다중행인지 아닌지 생각하고 -> all any 어떤 걸 사용할지 생각하기

제약 조건 추가하는 2가지 방법

profile
하이하잉

0개의 댓글