본문 바로가기
Database

SQL 데이터 조작문

by Doromi 2019. 4. 19.
728x90
반응형

DML

데이터 검색

- 기본 구조

SELECT   _리스트
  FROM   테이블_리스트
 
WHERE  조건;

 

EX)

STUDENT 테이블

 

 

  COURSE  테이블

 

ENROL 테이블

 


SELECT Sname, Sno
FROM STUDENT
WHERE Dept = '컴퓨터';

결과는 

실행 결과

 

똑같은 쿼리문이 있다.

SELECT STUDENT.Sname, STUDENT.Sno

FROM STUDENT 

WHERE STUDENT.Dept = '컴퓨터';

 


폐쇄 시스템(closed system)
테이블 처리 결과가 또 다시 테이블이 되는 시스템
중첩 질의문(nested query)을 구성할 수 있는 이론적 기초

 


SQL과 이론적 relational model의 차이점


- SQL의 테이블

  • 한 테이블 내에 똑같은 레코드(행) 중복 가능(기본키가 없어도 되고 그래서 중복이 허용)

  • 기본 키를 반드시 가져야 하는 것은 아님

  • 이론상 SQL의 테이블은 튜플의 집합이 아님

  • 같은 원소의 중복을 허용하는 다중 집합(multiset) 또는 백(bag)
    -> DISTINCT 명세 : 집합과 같은 결과를 만든다.

 


 

- 일반적인 형식

SELECT [ALL | DISTINCT] _리스트 [AS 별칭]
FROM       
테이블_리스트
[WHERE 조건]
[GROUP BY _리스트  

   [HAVING 조건]]
[ORDER BY _리스트  [ASC | DESC]];

 

 

  • 검색 결과에 레코드의 중복 제거 ( distinct를 썻을 때 관계대수에 프로젝션과 같음)

    SELECT   DISTINCT  Dept
     
    FROM     STUDENT;


  • 테이블의 열 전부를 검색하는 경우

    SELECT  *  FROM  STUDENT;


  • 조건 검색

    SELECT  Sno,Sname
      FROM     STUDENT
      WHERE   Dept = '컴퓨터' AND Year = 4;

  • 순서를 명세하는 검색(Default 가 오름차순)

    -
    SELECT    Sno, Cno
      FROM       ENROL
      WHERE    Midterm  > 90
      ORDER BY   Sno DESC, Cno ASC;

  • 산술식과 문자 스트링이 명세된 검색(이름 변경)

    SELECT    Sno AS 학번, '중간시험 = ' AS 시험Midterm + 3 AS 점수
      FROM      ENROL
      WHERE   Cno = 'C312';
  • 복수 테이블로부터의 검색(조인)

    - SELECT S.Sname, S.Dept, E.Grade
      FROM STUDENT S, ENROL E                     (variable 이름을 붙여서 사용)
      WHERE S.Sno = E.Sno AND E.CNO = 'C413';
  • 자기 자신의 테이블에 조인하는 검색

    같은 학과 학생의 학번을 쌍으로 검색해라.
    단, 첫 번째 학번은 두 번째 학번보다 작다.

    SELECT    S1.Sno, S2.Sno
      FROM       STUDENT S1, STUDENT S2        (같은 테이블끼리 조인하는 경우 variable 꼭!)
      WHERE    S1.Dept = S2.Dept
                                     AND S1.Sno < S2.Sno;

  • From 절에 조인 명세

    SELECT   Sname, Dept, Grade
      FROM      STUDENT JOIN ENROL ON   (STUDENT.Sno=ENROL.Sno)
      WHERE   ENROL.Cno = 'C413';

    SELECT    Sname, Dept, Grade
      FROM     STUDENT JOIN ENROL USING(Sno
      WHERE   ENROL.Cno = 'C413';

    SELECT    Sname, Dept, Grade
      FROM       STUDENT NATURAL JOIN ENROL         
      WHERE     ENROL.Cno = 'C413';

  • 집계 함수(aggregate function)을 사용한 검색

    - 집계 함수(COUNT, SUM, AVG, MAX, MIN)
    대상 데이터를 특정 그룹으로 묶은 다음 이 그룹에 대해 총합, 평균, 최대값, 최소값 등을 구하는 함수

    SELECT  COUNT(*)  AS  학생수
    FROM     STUDENT;

    SELECT   COUNT(DISTINCT Cno)
    FROM      ENROL
    WHERE   Sno = 300;

    COUNT 는 쿼리 결과 건수, 즉 전체 ROW 수를 반환하는 집계 함수
    테이블 전체 ROW는 물론 WHERE 조건으로 필터링 된  ROW 수를 반환


    SELECT   AVG(Midterm) AS 중간평균
    FROM      ENROL
    WHERE   Cno = C413;


  • GROUP BY 를 이용한 검색

    전체가 아닌 특정 그룹으로 묶어 데이터를 집계
    그룹으로 묶을 컬럼명이나 표현식을 group by 절에 명시해서 사용
    이 구문은 WHERE 와 ORDER BY절 사이에 위치한다.

    SELECT    Cno, AVG(Final)  AS  기말평균
    FROM        ENROL
    GROUP BY   Cno;
  • HAVING을 사용한 검색

    SELECT    Cno, AVG(Final)  AS  평균 
    FROM        ENROL
    GROUP BY   Cno
    HAVING      COUNT(*) > 3;

  • 부속 질의문(subquery)을 사용한 검색

    - 다른 질의문에 중첩되어 사용된 검색문
    - 형태 : 
    SELECT-FROM-WHERE-GROUP BY-HAVING
    - 중첩 질의문 : 부속 질의문을 포함하고 있는 질의문
    - IN 다음에 사용

    SELECT    Sname
    FROM     STUDENT
    WHERE    Sno  IN
                           (SELECT  Sno
                            FROM   ENROL
                            WHERE   Cno = 'C413');


    이 질의문을 조인으로 나타내면

    SELECT s.Sname
    FROM STUDENT s, ENROL e
    WHERE s.Sno = e.Sno and e.Cno = 'C413';


  • 부속 질의문을 사용한 검색(cont'd)

    NOT IN 의 경우 조인으로 바로 표현 불가능

    SELECT    Sname
    FROM        STUDENT
    WHERE    Sno NOT IN
                                 (SELECT   Sno
                                  FROM     ENROL
                                  WHERE   Cno = C413);

    C413을 수강하지 않는 학생들의 이름을 검색하는 것과 똑같다.

    만약 조인으로

    SELECT s.Sname
    FROM STUDENT s, ENROL e
    WHERE s.Sno = e.Sno and e.Cno <> 'C413';

    -> 이거와는 다르다.
    C413을 안듣는 학생이 만약 'C414'를 듣는 경우 결과에 나올 수 있기 때문에
    결과적으로 C413을 안듣는 학생도 남아있을 수 있기 때문

  • 부속 질의문을 사용한 검색(cont'd)
    - 학번이 500인 학생의 모든 기말 성적보다 좋은 학기말 성적을 받은 학생의
    학번과 과목번호를 검색하라.

    SELECT  Cno
    FROM   ENROL 
    WHERE  Final > ALL
                               (SELECT Final
                                FROM ENROL
                                WHERE Sno = 500);

  • LIKE 를 사용하는 검색

    - 서브 스트링 패턴(substring pattern) 비교 연산자
    - % 어떤 길이의 어떤 문자 스트링도 관계 없음을 의미
    - _ 문자 하나를 의미

    SELECT   Cno, Cname
    FROM      COURSE
    WHERE    Cno LIKE  'C%';  (C로 시작하는 문자열)


    'D%'(D로 시작하는) 
    'D_' (2글자인데 D로 시작하는)
    '_a_'(3글자인데 가운데 글자가 a인)
    'a%c'(a로 시작해서 c로 끝나는 모든)
    '%c%'(c가 들어간 모든 문자열) 


  • NULL 을 사용한 검색

    - NULL
    누락된 정보
    값은 있지만 모르는 값
    해당되지 않는 값
    의도적으로 유보한 값


  • EXISTS를 사용하는 검색

    튜플이 하나라도 있으면 TRUE
    없으면 FALSE
    EXISTS 이하 SELECT 문이 참(공집합이 아님) 일 때 본 SELECT 문을 실행한다.


    - 과목 'C413'에 등록한 학생의 이름을 검색하라.

    SELECT Sname
    FROM STUDENT
    WHERE EXISTS (SELECT 1 FROM ENROL WHERE ENROL.Sno = Sno
                                                                   AND Cno = 'C413');


  • EXISTS 를 사용하는 검색(cont'd)

    서브쿼리에서 결과가 하나도 안나오면 TRUE
    나오면 FALSE

    - 과목 'C413'에 등록하지 않은 학생의 이름을 검색하라.

    SELECT Sname
    FROM STUDENT
    WHERE NOT EXISTS
                             (SELECT 1 FROM ENROL WHERE Sno = STUDENT.Sno
                                                                             AND Cno = 'C413');

  • UNION이 관련된 검색

    두 개의 서브 쿼리를 합집합을 하는 키워드

    SELECT   Sno
    FROM      STUDENT
    WHERE   Year = 1

         UNION

    SELECT   Sno
    FROM     ENROL
    WHERE    Cno = 'C324';

일학년 학생의 학번을 검색
C324를 듣는 학생을 검색

일학년 학생이거나 C324를 듣는 학생을 검색하라

728x90
반응형

'Database' 카테고리의 다른 글

트랜잭션  (0) 2019.04.25
테이블의 제거와 변경  (0) 2019.04.17
SQL  (0) 2019.04.17
관계 대수의 확장  (0) 2019.04.16
순수 관계 연산자(조인,디비전)  (0) 2019.04.16