Skip to the content.

- 학습 목표 달성 확인 목록

- [] select 절에서 distinct 와 all의 차이점을 구분할 수 있는가?

/* 모든 데이터를 가져온다.*/
select all loc from room;

/* all은 생략할 수 있다*/
select loc from room;

/* 중복 값을 한 개만 추출할 때 distinct 를 붙인다.*/
select distinct loc from room;  

/* 컬럼이 2 개 이상일 때 
    그 컬럼들의 값이 중복될 경우만 한 개로 간주한다.*/
select distinct loc, name from room;

- [] order by 절을 이용하여 결과 데이터를 정렬할 수 있는가?

/* 기본 인덱스 컬럼을 기준으로 정렬한다.*/
select rno, loc, name
from room;

/* 이름의 오름 차순으로 정렬하기 */
select rno, loc, name 
from room
order by name asc;

/* asc는 생략 가능하다. */
select rno, loc, name
from room
order by name;

/* 이름의 내림 차순으로 정렬하기 */
select rno, loc, name
from room
order by name desc;

/* 이름은 오름차순, 지점명도 오름차순으로 정렬하기*/
select rno, loc, name
from room
order by name asc, loc asc;

/* 이름은 오름차순, 지점명은 내림차순으로 정렬하기*/
select rno, loc, name
from room
order by name asc, loc desc;

/* 지점명은 오름차순으로, 이름은 오름차순  정렬하기*/
select rno, loc, name
from room
order by loc asc, name asc;

- [] select 절에서 컬럼에 별명을 부여할 수 있는가?

/* 라벨명에 공백을 넣고 싶으면 '' 안에 작성한다.*/
select rno 'room no', loc location, name
from room;

/* 복잡한 형식으로 출력할 경우 라벨명(별명)을 부여한다.
    예) 강의실명(지점명)*/
select concat(name, '(', loc, ')')
from room;

select concat(name, '(', loc, ')') title
from room;

select count(*)
from room;

select count(*) cnt
from room;

select count(*) cnt
from room
where loc='서초';

- [] 질의 결과를 합치는 union과 union all의 차이점을 아는가?

/* select 결과 합치기 
   union : 중복 값 자동 제거*/
select distinct bank from stnt
union 
select distinct bank from tcher;

/* union all: 중복 값 제거 안함*/
select distinct bank from stnt
union all
select distinct bank from tcher;

- [] cross join과 natural join을 수행할 수 있는가?

/* cross join : 두 테이블의 데이터를 1:1로 모두 연결한다.*/
select mno, name from memb;
select mno, work, bank from stnt;
/* natural join: 같은 이름을 가진 컬럼 값을 기준으로 레코드를 연결한다. */
select m.mno, name, s.mno, work, bank
from memb m natural join stnt s;

- [] cross join의 문제점과 natural join의 문제점을 아는가?

서로 관계도 없는 데이터를 연결해 결과를 만든다

두 테이블에 같은 이름의 컬럼이 있을 경우 그 컬럼의 값이 일치하면 두 데이터를 연결하여 하나의 데이터로 만든다

강의명과 강사명이 서로 다른 데이터임에도 불구하고 컬럼이름이 같다는 이유호 연결 조건으로 사용되는 치명적인 문제가 있다.

컬럼의 이름이 다를 경우 두 데이터가 연결되지 못한다.

- [] cross join과 natural join의 문제점을 해결할 수 있는가?

**cross join**

select memb.mno, name, stnt.mno, work, bank
from memb cross join stnt;

//memb / stnt 와 같이 테이블을 명시해준다

**natural join1**

from lect l natural join mgr m

**natural join2**

from lect l join mgr m using(mno)

**natural join3**

from lect l join tcher t
on l.mno=t.mno

- [] inner join과 outer join을 수행할 수 있는가?

**inner join**

from memb m inner join stnt s on m.mno=s.sno

outer join

from lect l left outer join r l.rno=r.rno

- [] inner join과 outer join의 차이점을 아는가?

null같이 데이터가 존재하지 않는 경우가 있다 그렇게되면 inner join에서는 결과목록이 나오지않는 문제가 발생한다

outer join은 inner join의 문제점을 해결한 것인데

테이블에 조건에 해당하는 데이터가 없더라도 결과 목록에 나오게 하는 방법이다.

그래서 반드시 뽑아야 할 데이터가 있는 데이블을 가리킨다

- [] select 절에서 서브 쿼리를 사용할 수 있는가?

select la.lano, l.titl, m.name, s.work, la.rdt, r.name, m2.name, mr.posi
from lect_appl la
        inner join memb m on la.mno=m.mno
        inner join stnt s on la.mno=s.mno
        inner join lect l on la.lno=l.lno
        left outer join room r on l.rno=r.rno
        left outer join memb m2 on l.mno=m2.mno
        left outer join mgr mr on l.mno=mr.mno;

/* select 절에 서브쿼리 사용하기 */

/* => 1단계: 수강신청 데이터를 출력 */
select
  la.lano,
  la.lno,
  la.mno,
  date_format(la.rdt, '%Y-%m-%d') reg_dt
from lect_appl la;

/* => 2단계 : 서브 쿼리를 이용하여 강의명을 가져오기
   - 단, 컬럼 자리에 사용할 때는 결과 값이 한 개여야 한다.
   - 결과 값이 여러 개가 리턴된다면 컬럼 값으로 사용할 수 없기 때문에 오류이다.
   - 또한 컬럼 개수도 한 개여야 한다.
*/
select
    la.lano,
    (select titl from lect where lno=la.lno) as lect_title,
    la.mno,
    la.rdt
from lect_appl la;

/* => 3단계 : 서브 쿼리를 이용하여 학생명을 가져오기 */
select
    la.lano,
    (select titl from lect where lno=la.lno) as lect_title,
    (select name from memb where mno=la.mno) as stud_name,
    la.rdt
from lect_appl la;

- [] from 절에서 서브 쿼리를 사용할 수 있는가?

/* from 절에 서브쿼리 사용하기 */
/* 0단계 : 강의 정보를 가져온다. */
select
    l.lno,
    l.titl,
    l.rno,
    l.mno
from lect l;

/* 1단계 : 강의 상세 정보를 가져오는 select를 준비한다.
    => 서브 쿼리를 이용하여 강의실 이름과 매니저 이름, 직위 정보를 가져오기 */
select
    l.lno,
    l.titl,
    (select name from room where rno=l.rno) as room_name,
    (select name from memb where mno=l.mno) as manager_name,
    (select posi from mgr where mno=l.mno) as manager_posi
from lect l;

/* 2단계: 위에서 준비한 select 결과를 가상 테이블로 사용하여
             기존의 lect_appl 테이블과 조인한다.*/
select
    la.lano,
    /*(select titl from lect where lno=la.lno) as lect_title,*/
    (select name from memb where mno=la.mno) as stud_name,
    lec.titl,
    lec.room_name,
    lec.manager_name,
    lec.manager_posi
from lect_appl la
    join (select
                l.lno,
                l.titl,
                (select name from room where rno=l.rno) as room_name,
                (select name from memb where mno=l.mno) as manager_name,
                (select posi from mgr where mno=l.mno) as manager_posi
            from lect l) as lec on la.lno=lec.lno;

/* from 절에서 반복적으로 사용하는 서브 쿼리가 있다면,
 * 차라리 가상 테이블인 view로 정의해놓고 사용하는 것이 편하다.
 */
create view lect2 as
select
    l.lno,
    l.titl,
    (select name from room where rno=l.rno) as room_name,
    l.mno as manager_no,
    (select name from memb where mno=l.mno) as manager_name,
    (select posi from mgr where mno=l.mno) as manager_posi
from lect l;

/* 위의 질의문을 view를 사용하여 다시 작성해보자! */
select
    la.lano,
    (select name from memb where mno=la.mno) as stud_name,
    lec.titl,
    lec.room_name,
    lec.manager_name,
    lec.manager_posi
from lect_appl la
    join lect2 lec on la.lno=lec.lno;

- [] where 절에서 서브 쿼리를 사용할 수 있는가?

/* 과장 또는 대리 매니저가 담당하고 있는 수강 신청만 추출하기 */
select
    la.lano,
    /* (select titl from lect where lno=la.lno) as lect_title, */
    (select name from memb where mno=la.mno) as stud_name,
    lec.titl,
    lec.room_name,
    /* lec.manager_no, */
    lec.manager_name,
    lec.manager_posi
from lect_appl la
    join lect2 as lec on la.lno=lec.lno
where
    lec.manager_no in (select mno from mgr where posi in ('과장', '주임'));