190529_DAY35, <복습>, ,


<조인>

  • 두 개 이상의 테이블을 참조해서 데이터를 검색
  • from 뒤에 두개이상의 테이블 정의

조인의종류)

​ cross join, equi join, non-equi join, self join, outer join

  • cross join

    • Where절 없이 사용하는 조인
    • 각 테이블이 갖는 행의 곱만큼 결과행을 생성
    FROM emp, dept
  • equi join

    • 테이블 간의 공통된(연관된) 칼럼을 '='을 통해 비교
    FROM emp, dept
    WHERE emp.deptno = dept.deptno
  • non-equi join

    • 대소비교, 범위를 표현하는 연산자를 사용할 때
    FROM emp, salgrade
    WHERE emp.sal between salgrade.losal AND salgrade.hisal
  • self join

    • 같은 테이블을 두 번 이상 참조 조회.
    • 마치 테이블이 두개 이상 존재하는 것처럼 사용
    • 조회하고자 하는 데이터가 같은 행에 없을 때 사용! (SMITH의 MGR 7902(FORD)로 FORD의 정보 조회할 때)
    SELECT e1.ename, e2.ename
    FROM emp e1, emp e2
    WHERE e1.ename = 'SMITH'
        AND
        e1.mgr = e2.empno;
  • outer join

    • 조회 결과행에 배제된 (빠진) 행을 출력하고 싶을 때 사용
    SELECT e1.ename || 
    '사원의 상사는'||
    e2.ename||
    '입니다.'
    FROM emp e1, emp e2
    WHERE e1.mgr = e2.empno;
    -- 기대 : 14명 사원 각각의 직속 상사명 출력
    -- 결과 : 13row... 뭔가 빠졌네
    -- 원인 : 매핑되지 않는 행이 발생
        -- 예
        WHERE e1.mgr = e2.empno;
        -- KING 의 mgr은 NULL , NULL = 데이터 => 결과도 NULL, 검색행에 누락됨.
        -- ※ NULL은 비교, 연산, 할당 불가!
    
    -- 해결 : where e1.mgr = e2.empno(+);
    
    SELECT e1.ename || 
    '사원의 상사는'||
    NVL(e2.ename, '[미정]')||
    '입니다.' "상사는 누구?"
    FROM emp e1, emp e2
    WHERE e1.mgr = e2.empno(+);

<ANSI 조인>

  • 표준조인, DBMS종류와 상관없이 실행.
  • FROM 뒤에 ',' 콤마를 사용하지 않는다.
  • cross join, inner join, natural join, outer join
  • cross join

    FROM emp CROSS JOIN dept
  • inner join

    FROM emp INNER JOIN dept
    -- ON 공통칼럼 비교 -- 반드시 ON 정의, but USING 절로 대체가 가능
    ON emp.deptno = dept.deptno
    
    USING (deptno)
    
    WHERE 추가 기능 -- 추가적인 조건 검색
  • natural join

    • 두 테이블을 비교해서 동일한 이름의 컬럼을 자동 using 해준다
    • 단, 단점으로는 동일한 이름으로 의도치 않은 컬럼도 묶어버림.
    FROM emp NATURAL JOIN dept
  • outer join

    FROM emp (LEFT 혹은 RIGHT 혹은 FULL) [OUTER] JOIN dept
    
    -- 오라클 문법에서는 모자란쪽(부족한쪽) 에 (+)를 붙이지만
    -- 
    SELECT e1.ename || 
    '사원의 상사는'||
    NVL(e2.ename, '[미정]')||
    '입니다.' "상사는 누구?"
    FROM emp e1 LEFT OUTER JOIN emp e2
    ON e1.mgr = e2.empno;

<서브쿼리>

  • 특정 테이블에서 검색된 결과를 다른 테이블에 전달하여 새로운 결과를 검색 할 때 사용

  • 메인 쿼리 이외의 추가되는 모든 SELECT문

    SELECT 컬럼명 -- 메인쿼리
            (SELECT ~ FROM ~) -- 서브쿼리
    
    FROM 테이블명
            (SELECT ~ FROM ~) -- 서브쿼리, 인라인 뷰
                            -- 서브쿼리의 결과가 하나의 테이블에 대한 뷰처럼 사용되기에 이렇게 부르는 것이다. 
    
    출처: https://narwhals.tistory.com/9 [IT 공부 블로그]
    
    WHERE 컬럼명 연산자 데이터 
            논리연산자( OR | AND )
            컬럼명 연산자 ( SELECT ~ FROM ~ ) -- 서브쿼리
    
    -- 단 서브쿼리에서 지켜주어야 하는 것!
    -- SELECT 서브쿼리는 1행 1열
    -- FROM 서브쿼리는 1행 1열도 되고, 다수행 다수열도 가능
    -- WHERE 서브쿼리는 결과행 1개 : 연산자 =, > , <
    --                        2개이상 : 연산자에 등호, 부등호를 사용 불가!! , 에러발생, 이를 IN, ANY, SOME, ALL, EXISTST 등(Multi Row Operator, 다중 행 연산자)를 통해 해결!
    -- 다중 행 연산자 사용
    WHERE deptno IN (
                       SELECT deptno
                        FROM dept
                        WHERE deptno < 30
                   )
    WHERE sal > ANY (
                       SELECT sal
                       FROM emp
                       WHERE deptno = 20
                 )
    
    WHERE sal > ALL (
                       SELECT sal
                       FROM emp
                       WHERE deptno = 20
                 )    
    
    WHERE exists (서브쿼리) -- TRUE FALSE로 반환, 결과행 0개 : FALSE, 결과행 1개이상 : TRUE

<DDL.>

  • CREATE, DROP, ALTER, RENAME, TRUNCATE

<테이블생성>

CREATE TABLE 테이블명
(
    컬럼명1 자료형, 
    컬럼명2 자료형
);
--테이블 객체생성! 구조만생성, 데이터는 없음 => 앞으로 INSERT명령문 통해 행단위의 입력!

<테이블생성2 - 서브쿼리를 이용한 테이블 생성>

  • 기존 테이블의 구조(컬럼, 자료형) 와 데이터를 복사

  • 제약(CONSTRAINT)은 복사에서 제외!

  • NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK

  • 형식)

    -- 예전에 했던 복사 테이블 생성 방식
    
    SELECT tname, tabtype 
    FROM tab
    WHERE tname LIKE '%E%';
    
    SELECT tname, tabtype
    FROM tab
    WHERE tname LIKE 'EM%';
    
    DROP TABLE emp2;
    
    CREATE TABLE emp2
    AS SELECT * FROM emp;

<테이블 생성3 >

  • 서브쿼리를 이용한 테이블 생성 , 원하는 컬럼과 행만 복사

    CREATE TABLE 테이블명
    AS 서브쿼리;
    
    SELECT tname, tabtype from tab; -- 조회
    
    FROM emp
    WHERE deptno = 30;
    
    -- 생성
    CREATE TABLE emp3
    AS SELECT empno, ename, job -- 선택컬럼, 모든컬럼은 * 로
    FROM emp -- 원본테이블
    WHERE deptno = 30; -- 행제어 WHERE절 생략시 모든 행
    
    --오라클 조회어
    DESC emp3;
    

<데이블 생성4>

  • 서브쿼리를 이용한 테이블 생성 : 구조(컬럼, 자료형)만 복사

    CREATE TABLE emp4
    AS SELECT * FROM emp
    WHERE '길동' = '라임';
    -- 1 = 0,  1>2
    
    select * from emp4;
    -- no rows selected

<테이블의 구조 변경하기> ALTER

  • 컬럼추가, 컬럼삭제, 컬럼의 자료형, 바이트 수를 변경

    ALTER TABLE emp4
    ADD  (email  varchar2(20));
    --==> Table altered.
    
    desc emp4;
    
    ALTER TABLE emp4
    DROP COLUMN email;
    --==> 테이블 변경
    ※ALTER 정리
    ALTER TABLE 테이블명
    - 컬럼 추가 : ADD ( 추가 컬럼명 자료형 )
    - 컬럼 수정 : MODIFY ( 기존 컬럼명 자료형 )
    - 컬럼 삭제 : DROP COLUMN 삭제할 컬럼명
    - 컬럼이름변경 : RENAME COLUMN 기존컬럼명 TO 새컬럼명
    - 컬럼사용안함 : SET UNUSED (컬럼명)
    - UNUSED 설정 된 컬럼들 삭제 : DROP UNUSED COLUMN

<테이블 객체 삭제>

  • 형식)

    DROP TABLE 테이블명;
    
    SELECT tname, tabtype from tab;
    - 시스템테이블
    - 연결계정이 갖는 테이블명과 테이블 타입을 출력
    
    DROP TABLE emp2; 
    

<테이블 객체 이름 변경>

  • 형식)

    RENAME old_객체명  TO  new_객체명;
    
    CREATE TABLE emp2
    AS SELECT * FROM emp;
    
    SELECT tname, tabtype from tab;
    
    RENAME emp2 TO 사원테이블;
    
    select tname, tabtype from tab;
    
    

<테이블의 전체 데이터 지우기>

- 형식)

  - TRUNCATE TABLE 테이블명;

  ```SQL
  SELECT COUNT (*) FROM 사원테이블;

  TRUNCATE table 사원테이블;  

  ---> Table truncated. (테이블이 잘렸습니다!! : 테이블내의 모든 데이터가 삭제 되었음)
  ---> ※주의: truncate명령어를 통해 삭제된 데이터는 복구가 불가능!!

<DML.> Data Manipulation Language : 데이터 조작어

  • INSERT(입력), DELETE(삭제), UPDATE(수정, 재입력) --행단위 실행

<INSERT.> : 테이블에 (행) 데이터 추가 (최초입력)!

  • 형식

    INSERT INTO 테이블명 [( 컬럼명1, 컬럼명2, 컬럼명3)] -- 생략가능
                VALUES (데이터1, 데이터2, 데이터3);
                --만약, 테이블명 뒤에 컬럼명을 생략하는 경우
                -- 테이블 구조에 있는 순서에 따라 전체 컬럼명이 명시된 것으로 간주!!
                ---> 명시된 컬럼의 갯수와 데이터 갯수는 반드시 일치.
                  ---> 컬럼의 순서에 맞는 자료형 데이터가 와야함.
    
    

INSERT INTO dept
VALUES (50, '대전', '자재부');


create table dept2
as select * from dept;

select * from dept2;

insert into dept2 (deptno, dname, loc)
values ( 50, '기획부', '남터');

select * from dept2;


<데이터 입력시 에러 예>

```sql
insert into dept2 (deptno, dname)  values (60,'자재부','대전');
==> ORA-00913: too many values  

insert into dept2 (deptno, dname)  values (60);
==> ORA-00947: not enough values

insert into dept2 (deptno, dname, loc)  values ('자재부','대전',60);
또는
insert into dept2     values ('자재부','대전',60);
                               *
==> ORA-01722: invalid number

<NULL값 입력방법>

  • 컬럼명을 명시하지 않는다.

       create table dept3
       as select * from dept;
    
       insert into dept3  (deptno, dname)
                   values (50    , '개발부');
    
    select * from dept3;
문제) 아직 부서의 위치가 정해지지 않은 부서는 어디?
     select dname
     from   dept3
     where  loc  is null;   
     ==> 개발부

문제) 데이터가 들어가는 자리에 직접 null을 명시.
   insert into dept3  (deptno, dname, loc)  values (60,'기획부', null);
   insert into dept3  values (60,'기획부', null); -- 이렇게 줄일 수 있다.

 select * from dept3;

 문제) 데이터가 들어가는 자리에 ''를 입력
insert into dept3 (deptno, dname, loc)
 values (70,    '총무부', '');

 문제) 아직 부서의 위치가 정해지지 않은 부서는 어디?
    select dname
    from dept3
    where loc is null;

<서브쿼리로 행 추가>

  • 형식

    create table dept4
    as select * from dept
       where 1=0;        -- dept테이블의 구조(컬럼)만 복사, 데이터 복사X
    
    select * from dept4;
    ---> no rows selected       
    
    insert into dept4
    select * from dept; 
    
    문제) dept5테이블을 생성하고(dept테이블의 구조만 복사, 데이터복사X)
         dept테이블의 20,40번 부서의 정보(부서번호, 부서이름)를 서브쿼리를 통해 입력하시오.
    drop table dept5;
    
         create table dept5
         as select * from dept
            where 1=0;    
    
         insert into dept5           ---> 컬럼명 생략은 전체 컬럼 즉, (deptno, dname, loc) 생략 간주
         select deptno, dname       -- 2열
         from   dept   -- 4행
         where  deptno  IN (20,40);  -- 2행
    
    ---> ORA-00947: not enough values  : 데이터가 충분하지 않음!!
    
         insert into dept5 (deptno, dname)        
         select deptno, dname       -- 2열
         from   dept   -- 4행
         where  deptno  IN (20,40); 
    ---> 2 rows created.
    
    문제) 만약 dept테이블의 부서번호가 10단위로 구성되어 있다고 가정했을때
         10,30,50,70,....번의 부서의 정보를 dept5테이블에 옮기시오.(서브쿼리를 통한 행추가!!)
         ----------------
         십의 자리수가 홀수인 부서!!
    
         insert into dept5 -- (deptno, dname, loc)
         select deptno, dname, loc
         from   dept
         where  mod( deptno/10,  2)  = 1;
    ---> 2 rows created.     
    
    SQL> select * from dept5;
    
        DEPTNO DNAME                        LOC
    ---------- ---------------------------- --------------------------
            20 RESEARCH
            40 OPERATIONS
            10 ACCOUNTING                   NEW YORK
            30 SALES                        CHICAGO

<다중테이블에 다중 로우(행) 입력>

  • 형식

    INSERT ALL
        INTO 테이블명1 VALUES (COL, COL, COL)
        INTO 테이블명2 VALUES (COL, COL, COL)
        INTO 테이블명3 VALUES (COL, COL, COL)
    SELECT COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9
    FROM 테이블명;
    
    문제) emp테이블에서 30번 부서 사원들의 정보를 얻어서(조회해서)
    emp_hir(구조만 : empno, enmae, hiredate)테이블과
    emp_mgr(구조만 : empno, ename, mgr )테이블에 데이터를 입력하시오.
    
    CREATE TABLE emp_hir
    AS SELECT empno, ename, hiredate
    FROM emp
    WHERE 1 = 0;
    
    CREATE TABLE emp_mgr
    AS SELECT empno, ename, mgr
    FROM emp
    WHERE 1 = 0;
    
    INSERT ALL
        INTO emp_hir VALUES (empno, ename, hiredate)
        INTO emp_mgr VALUES (empno, ename, mgr)
    SELECT empno, ename, hiredate, mgr
    FROM emp
    WHERE deptno = 30;

<조건 (WHEN)에 의해 다중테이블에 다중 로우 입력하기>

  • 형식

    WHEN 조건식 THEN 실행할 문장
    
    테스트테이블 생성)
    CREATE TABLE emp_hir2
    AS SELECT empno, ename, hiredate
    FROM emp
    WHERE 1 = 0;
    
    CREATE TABLE emp_sal
    AS SELECT empno, ename, sal
    FROM emp
    WHERE 1 = 0;
    
    문제) 1982년 이후에 입사한 사원의 정보를 emp_hir2테이블에 입력하고
    급여가 2000이상을 받는 사원의 정보를 emp_sql테이블에 입력하시오.
    (insert all사용, 데이터정보는 emp테이블에서 조회)
    
    INSERT all
        WHEN hiredate >= to_date('1982/01/01')
        THEN INTO emp_hir2 VALUES (empno, ename, hiredate)
        WHEN sal >= 2000
        THEN INTO emp_sal VALUES (empno, ename, sal)
    SELECT empno, ename, hiredate, sal
    FROM emp;
    

<UPDATE.> : 기존 데이터에 대한 수정, 갱신, 재입력

  • 형식

    UPDATE 테이블명
    SEL 컬럼명1 = (변경할) 데이터, 컬럼명2 = (변경할) 데이터
    [WHERE 조건식];
    
    -- 주의 : UPDATE와 DELETE문을 실행하기 전 반드시 WHERE절 사용을 고려하자
    -- 왜? 만약 WHERE절 사용하지 않는다면 전체행에 대한 수정 또는 삭제가 실행되기 때문
    
    DROP TABLE dept3;
    
    CREATE TABLE dept3
    AS SELECT * FROM dept3;
    
    SELECT * FROM dept3;
    
    문제) 30번 부서의 급혀를 10% 인상하라
    DROP TABLE emp3;
    
    CREATE TABLE emp3
    AS SELECT empno, ename, sal, deptno
    FROM emp;
    
    UPDATE emp3
    SET sal = sal*1.1
    WHERE deptno = 30;
    
    SELECT * FROM emp3;

<서브쿼리를 이용한 데이터 수정>

DROP TABLE dept4;

CREATE TABLE dept4
AS SELECT * FROM dept;

문제) 부서번호 20번의 부서명과 지역을 40번 부서와 동일하게 변경하시오!

UPDATE dept4
SET dname = (
            SELECT dname
            FROM dept4
            WHERE deptno = 40
            ),
     loc = (
             SELECT loc
             FROM dept4
             WHERE deptno = 40
             )
WHERE deptno =20;

UPDATE dept4
SET ( dname, loc ) = (
             SELECT dname, loc
             FROM dept4
             WHERE deptno = 40
             ) --from where이 동일함으로 이렇게 묶어 줄 수 있다!
WHERE deptno =20;

<DELETE.> : ( 행 단위 )데이터 삭제명령어

  • 형식

    DELETE FROM 테이블명 --전체 행 삭제(모든데이터), 보통 drop해서 드문 일
    [WHERE 조건식]; --특정 행 삭제
    
    문제) 부서테이블(DEPT4)내의 모든 부서를 삭제하시오.
    DELETE FROM dept4;
    
    문제) DEPT4테이블을 유지한 상태(rollback하지 말고)에서     
         DEPT테이블의 데이터들을 복사(입력)하시오.
    UPDATE dept4
    VALUES (데이터);
    
    INSERT INTO dept4
    서브쿼리;
    
    INSERT INTO dept4
    SELECT deptno, dname, loc
    FROM dept;
    
    SELECT * FROM dept4;
    문제) 20번 부서를 삭제하시오.
    
    DELETE FROM dept4
    WHERE deptno = 20;
    
    SELECT * FROM dept4;
    
    문제) SALES부서에 속한 사원들을 사원테이블(EMP3)에서 삭제하시오.
    DROP TABLE emp3;
    
    CREATE TABLE emp3
    AS SELECT * FROM emp;
    
    SELECT * FROM emp3;
    --------------------------------
    delete from emp3
    where  deptno = 30;
    
    delete from emp3
     where  deptno = (select deptno
                          from  dept
                          where dname='SALES');    
    ----> 6 rows deleted.
    
    select empno, ename, deptno, dname
    from       emp3   inner join dept
    using   (deptno);

<MERGE.> 합병(병합)

  • 구조가 같은 두 개의 테이블을 하나의 테이블로 합치는 기능.

  • 기존에 존재하는 행이 있다면 새로운 값으로 갱신(update)되고
    존재하지 않는 행이 있다면 새로운 행으로 추가(insert)해라!!

  • 형식

       MERGE INTO 기준테이블명   별명
           USING  참조테이블명   별명
           ON (매칭 조건식)
       WHEN MATCHED      -- 매칭되는 행이 있다면
          THEN 업데이트문
       WHEN NOT MATCHED  -- 매칭되는 행이 없다면 
          THEN 추가문;
    
    CREATE TABLE emp11 -- 기분테이블
    AS SELECT * FROM emp;
    
    CREATE TABLE emp12 -- 참조테이블
    AS SELECT * FROM emp
    WHERE job = 'MANAGER';
    
    UPDATE emp12 SET job = '사원';
    INSERT INTO emp12 (empno, ename, job,   mgr, hiredate, sal, comm, deptno)
               VALUES (9000, '나길동','사원', 7788, sysdate, 2000, null, 30); -- emp11에는 없는 사원
    
    SELECT empno, ename, job FROM emp12;
    
    MERGE INTO emp11 e1
        USING emp12 e2
        ON (e1.empno = e2.empno)
    WHEN MATCHED -- 매칭되는 행이 있다면
        THEN -- 업데이트(변경)문
            UPDATE SET --SET앞에 생략
                e1.job = e2.job,
                e1.mgr = e2.mgr,
                e1.sal = e2.sal,
                e1.comm = e2.comm,
                e1.deptno = e2.deptno
    WHEN NOT MATCHED -- 매칭되는 행이 없다면
        THEN -- 추가문
            INSERT VALUES (e2.empno, e2.ename, e2.job, e2.mgr, e2.hiredate, e2.sal, e2.comm, e2.deptno);
궁금상자
- 테이블 조회하기
    SELECT * FROM all_all_tables;
- 테이블 목록 조회(접속한 계정)
    SELECT * FROM tabs; -- 그런데 이렇게 하면 어마어마하게 많이 나온다.
    SELECT tname, tabtype FROM tab; -- 이정도로만 조회하도록 하자!
- 테이블을 지우고 싶은데 일일이 지우기에는 너무 귀찮다... 어떻게 하면 편하게 지울 수 있을 까?
    모든 테이블을 지울 때에는
    SELECT 'DROP TABLE "' || TABLE_NAME || '" CASCADE CONSTRAINTS;' FROM user_tables;

    CASCADE CONSTRAINTS는 부모, 자식 테이블에서 우선적으로 자식테이블을 삭제한 후에야 부모테이블을 지울 수 있는데 이 옵션으로 참조되어진 모든 값을 오류없이 같이 지워버리기 때문에 사용, 단 참조값들은 참조 연결만 끊어지고 삭제되지 않는다. = 제약조건 삭제
- DELECATE TRUNCATE DTOP의 차이 (밑의 표 참조)    
DELETE( DML ) 원하는 데이터 삭제 테이블 용량 감소 안한다.
TRUNCATE ( DDL ) 테이블 자료 모두 삭제 원하는 데이터만 삭제 불가, 복구가 힘듬( ROLLBACK 안됨. )
DROP ( DDL ) 테이블 자체 삭제

190528_DAY ANSI JOIN 복습, 서브쿼리, DDL시작


============================= JOIN문제 ============================================
※아래의 문제들을 ANSI JOIN으로 해결하시오.

문제1) 사원들의 이름, 부서번호, 부서이름을 출력
select ename, emp.deptno, dname
from emp inner join dept
on emp.deptno = dept.deptno; -- inner join 들어왔다면 반드시,, 반드시 on이 뒤따라야 함, 공통항목 이어주는

select ename, deptno, dname
from emp inner join dept
using (deptno);

select ename, deptno, dname
from emp natural join dept;

문제2) 부서번호가 30번인 사원들의 이름, 직급, 부서번호, 부서위치를 출력
select ename, job, e.deptno, loc
from emp e inner join dept d --
on e.deptno = d.deptno
where e.deptno = 30; --where 말고 and e.deptno = 30; 으로 해도 같은 결과, 단 동등조건과 추가 조건 나눈다면 where을 사용해야 한다. 

select ename, deptno, loc
from emp natural join dept -- natural join은 using 사용하는것과 동일하다.
where deptno = 30;

select ename, deptno, loc
from emp inner join dept
using (deptno)
where deptno = 30;

문제3) 커미션을 받는 사원의 이름, 커미션, 부서이름, 부서위치 출력(커미션 0은 제외)
select ename, comm, dname, loc
from emp natural join dept
where comm <> 0
and comm is not null;

select ename, comm, dname, loc
from emp inner join dept
on emp.deptno = dept.deptno
where comm != 0
and comm is not null;

문제4) DALLAS에서 근무하는 사원들의 이름, 직급, 부서번호, 부서이름을 출력
select ename, job, deptno, dname
from emp natural join dept
where loc = 'DALLAS';

select ename, job, deptno, dname
from emp inner join dept
on emp.deptno = dept.deptno
where loc = 'DALLAS';

문제5) 사원이름에 'A'가 들어가는(포함하는) 사원들의 이름과 부서이름을 출력
select ename, dname
from emp inner join dept
on emp.deptno = dept.deptno
where ename like '%A%';


문제6) 사원이름과 직급, 급여, 급여등급을 출력
select ename, job, sal, grade
from emp inner join salgrade
on sal between losal and hisal;

/*
select ename, job, sal, grade, dept.deptno --오류 내가 ㅠㅠ
from emp left join salgrade
on emp.deptno = dept.deptno
where grade between losal and hisal;
*/

문제7) 사원들의 이름과 그 사원과 같은 부서에 근무하는 사원의 사원명, 부서번호를 출력
       ===> 자기 이름을 제외한 동료(56행) 정보 출력!!
select e1.ename, e2.ename deptno
from emp e1 inner join emp e2
on e1.deptno = e2.deptno
where e1.ename <> e2.ename; --혹은 e1.empno != e2.empno



/*
select e1.ename, e2.ename e2.deptno --오류 내가  ㅠㅠ
from emp e1 left join dept e2
on e1.deptno = e2.deptno;
where e1.ename != e2.ename;
*/

★<서브쿼리> Sub Query

  • 특정 테이블에서 검색된 결과를 다른 테이블에 전달하여 새로운 결과를 검색 할 때 사용.

    문제) JAMES 사원이 근무하는 부서이름을 출력
    select deptno
    from emp
    where ename = 'JAMES'; -- 30번 부서 근무
    
    select dname
    from dept
    where deptno = 30; -- 부서명 SALES
    
    select dname
    from dept
    where deptno = (select deptno
                    from emp
                    where ename = 'JAMES');
    결과)
    DNAME
    ----------------------------
    SALES
    
    --===========================================================================
    
    문제) FORD사원과 동일한 직책을 가진 사원에 대해 사원번호, 사원명, 급여, 직책을 출력하시오
    select empno, ename, sal, job
    from emp
    where job = 'ANALYST';
    
    select job
    from emp
    where ename = 'FORD';
    
    select empno, ename, sal, job
    from emp
    where ename <> 'FORD'
            and
            job = (select job
                     from emp
                     where ename = 'FORD');
    결과)
         EMPNO ENAME                       SAL JOB
    ---------- -------------------- ---------- ------------------
          7788 SCOTT                      3000 ANALYST
    
     --===========================================================================
    
     문제) MARTIN사원의 급여와 동일하거나 더 많이 받는 사원의 사원명, 급여를 출력
     select sal
     from emp
     where ename = 'MARIN';
    
     select ename, sal
     from emp
     where sal >= ( 
             select sal
             from emp
             where ename = 'MARTIN'
             );
    
     결과)
     ENAME                       SAL
    -------------------- ----------
    ALLEN                      1600
    WARD                       1250
    JONES                      2975
    MARTIN                     1250
    BLAKE                      2850
    CLARK                      2450
    SCOTT                      3000
    KING                       5000
    TURNER                     1500
    FORD                       3000
    MILLER                     1300
    
     --===========================================================================
    
     문제) DALLAS에서 근무하는 사원의 이름, 부서번호를 출력
    
     select loc
     from dept
     where loc = 'DALLAS';
    
     select ename, deptno
     from emp
     where deptno = 
                     (
                         select deptno
                         from dept
                         where loc = 'DALLAS'
                     );
    
     select ename, deptno
     from emp natural join dept
     where loc = (
                 select loc
                 from dept
                 where loc = 'DALLAS'
                 );
    
     select ename, deptno
     from emp inner join dept
     using (deptno)
     where loc = (
                 select loc
                 from dept
                 where loc = 'DALLAS'
                 );
    
     결과)
     ENAME                    DEPTNO
    -------------------- ----------
    JONES                        20
    FORD                         20
    ADAMS                        20
    SMITH                        20
    SCOTT                        20
    
    --===========================================================================
    SUB QUERY 문제들
    문제)
    SALES부서에서 근무하는 모든 사원의 이름과 급여, 부서번호를 출력
    SELECT deptno
    FROM dept
    WHERE dname = 'SALES';
    
    SELECT ename, sal, deptno
    FROM emp
    WHERE deptno =
                (
                    SELECT deptno
                    FROM dept
                    WHERE dname = 'SALES'
                  );
    
    결과)
    ENAME                       SAL     DEPTNO
    -------------------- ---------- ----------
    ALLEN                      1600         30
    WARD                       1250         30
    MARTIN                     1250         30
    BLAKE                      2850         30
    TURNER                     1500         30
    JAMES                       950         30
    
    --===========================================================================
    
    문제) 자신의 직속상사가 KING인 사원의 이름과 급여, 직속상사의 사원번호를 출력.
    SELECT empno
    FROM emp
    WHERE ename = 'KING';
    
    SELECT ename, sal, mgr
    FROM emp
    WHERE mgr = (
                   SELECT empno
                    FROM emp
                    WHERE ename = 'KING'
                );
    결과)
    ENAME                       SAL        MGR
    -------------------- ---------- ----------
    JONES                      2975       7839
    BLAKE                      2850       7839
    CLARK                      2450       7839
    
    --===========================================================================
    
    문제) 평균급여보다 많은 급여를 받은 사원들의 사번, 사원명, 급여를 출력.(급여 내림차순)                
    SELECT AVG(sal)
    FROM emp;
    
    SELECT empno, ename, sal
    FROM emp
    WHERE sal >= (
                SELECT AVG(sal)
                FROM emp
                )
    ORDER BY SAL DESC;
    
    결과)
         EMPNO ENAME                       SAL
    ---------- -------------------- ----------
          7839 KING                       5000
          7902 FORD                       3000
          7788 SCOTT                      3000
          7566 JONES                      2975
          7698 BLAKE                      2850
          7782 CLARK                      2450
    
    --===========================================================================
    
    문제) 10번 부서의 사원 중 전체(사원) 최대급여를 받는 사원과 동일한 급여를 받는 사원의 사원번호와 사원명을 출력.
    (문제 조금 이상...)
    SELECT MAX(sal)
    FROM emp
    WHERE deptno = '10';
    
    SELECT empno, ename --열제어
    FROM emp
    WHERE sal >= (
                   SELECT MAX(sal)
                    FROM emp
                    WHERE deptno = '10'
                );
    
    SELECT empno, ename --열제어
    FROM emp
    WHERE     sal = (
                    SELECT MAX(sal)
                    FROM emp
                  )
            and
            deptno = 10;
    
    결과)
         EMPNO ENAME
    ---------- --------------------
          7839 KING
    
    --===========================================================================
    
    문제) 10번 부서에서 근무하는 사원의 이름과 10번 부서의 부서명을 출력하시오.
    SELECT a,b,c,d,e,f
    FROM (SELECT a,b,c FROM test1), (SELECT d,e,f FROM test2);
    --FROM 뒤에 테이블명(행렬구성)도 올 수 있고 서브쿼리(결과값 행렬)도 위치 할 수 있다.
    
    SELECT empno, ename, sal --에러발생 : 서브쿼리에 sal컬럼에 대한 정보가 없기 때문
    FROM (SELECT empno, ename FROM emp);
    
    SELECT ename, dname
    FROM emp, (select dname from dept where deptno = 10 )
    WHERE deptno = '10';
    
    SELECT ename, (select dname from dept where deptno = 10 ) --아무거나 쓸 수는 없다.
    --SELECT 옆, WHERE에는 1행 1열 값만 들어갈 수 있고, FROM에는 행렬만 들어가면 관계 없다.
    FROM emp
    WHERE deptno = '10';
    
    결과)
    ENAME                DNAME
    -------------------- ----------------------------
    CLARK                ACCOUNTING
    KING                 ACCOUNTING
    MILLER               ACCOUNTING
    
    --추가 정보
    SELECT ename, (SELECT '몸에 좋은 딩꼬' FROM dual ) MSG
    FROM emp
    WHERE deptno = '10';
    
    SELECT ename, (SELECT '몸에 좋은 딩꼬', '이것도 될까?'  --이건 안된다 1행 2열은 안됨! 
                   FROM dual ) MSG
    FROM emp
    WHERE deptno = '10';
    
    ORA-00913: too many values --이 오류 발생
    
    --===========================================================================
    
    문제) BLAKE와 같은 부서에 있는 사원들의 이름과 입사일자, 부서번호를 출력하시오.
    SELECT ename, hiredate, deptno
    FROM EMP
    WHERE deptno = 30;
    
    SELECT ename, hiredate, deptno
    FROM emp
    WHERE deptno = (
                    SELECT deptno
                    FROM emp
                    WHERE ename = 'BLAKE'
                    );
    
    결과)
    ENAME                HIREDATE     DEPTNO
    -------------------- -------- ----------
    ALLEN                81/02/20         30
    WARD                 81/02/22         30
    MARTIN               81/09/28         30
    BLAKE                81/05/01         30
    TURNER               81/09/08         30
    JAMES                81/12/03         30
    
    --===========================================================================
    
    추가)
    만약 BLAKE라는 이름을 갖은 신입이 새로 들어왔다면?!
    --사원추가 (다른 부서에 BLAKE 등장!)
    INSERT INTO emp ( empno, ename, hiredate, deptno )
                values ( 8000, 'BLAKE', sysdate, 20 );
    --하고 나서 다시 위~~의 명령어를 다시 입력하면?
    ORA-01427: single-row subquery returns more than one row
    --에러 발생! 이렇게 데이터의 크기가 커지면 문제가 발생 할 수 있는 것.
    
    --해결방법!
    SELECT ename, hiredate, deptno
    FROM emp
    WHERE deptno = 30 or deptno = 20;
    
    SELECT ename, hiredate, deptno
    FROM emp
    WHERE deptno in (30,20); --이렇게 줄일 수 있다.
    
    --다시 위~~~ 의 명령어로 돌아가서
    SELECT ename, hiredate, deptno
    FROM emp
    WHERE deptno IN (
                    SELECT deptno
                    FROM emp
                    WHERE ename = 'BLAKE'
                    );
    --실행이 너~ 어어어 무 잘된다!
    
    ENAME                HIREDATE     DEPTNO
    -------------------- -------- ----------
    BLAKE                19/05/28         20
    SMITH                80/12/17         20
    ALLEN                81/02/20         30
    WARD                 81/02/22         30
    JONES                81/04/02         20
    MARTIN               81/09/28         30
    BLAKE                81/05/01         30
    SCOTT                87/04/19         20
    TURNER               81/09/08         30
    ADAMS                87/05/23         20
    JAMES                81/12/03         30
    FORD                 81/12/03         20
    

<다중 행 서브 쿼리>

  • 서브쿼리의 결과행이 여러개 ( 2개행 이상 )
  • 반드시 다중 행 연산자 ( Multiple Row Operator) 와 함께 사용

※다중 행 연산자

  • IN : 메인쿼리의 비교조건이 서브쿼리의 결과중에서 하나라도 일치하면 참
  • su in (10,20,30)
  • ANY, SOME : 메인쿼리의 비교조건이 서브쿼리의 결과와 하나이상 일치하면 참.
  • ALL : 메인쿼리의 비교조건이 서브쿼리의 결과와 모든 값이 일치하면 참.
  • EXISTS : 메인쿼리의 비교조건이 서브쿼리의 결과중에서 만족하는 값이 하나라도 존재하면 참
SELECT *
FROM dept
WHERE exists(SELECT * --서브쿼리 결과
              FROM emp
             WHERE deptno = 10);
    DEPTNO DNAME                        LOC
---------- ---------------------------- --------------------------
        10 ACCOUNTING                   NEW YORK
        20 RESEARCH                     DALLAS
        30 SALES                        CHICAGO
        40 OPERATIONS                   BOSTON
--위와 달리! WHERE절을 바꿔보자!
SELECT *
FROM dept    
WHERE exists(SELECT * 
              FROM emp
             WHERE deptno = 40); --10이 아니라 40으로!
--이러면 결과 안나온다, 데이터 존재 유무에 따라 SELECT, DELETE, UPDATE, INSERT시 제어하는 역할로 사용.
--서브쿼리의 결과가 있느냐 없느냐만 체크
no rows selected --결과값
사용법)
WHERE EXISTS (서브쿼리)
WHERE NOT EXISTS (서브쿼리)

--===========================================================================

문제)
급여를 3000이상 받는 사원이 소속된 부서와 동일한 부서에 근무하는 사원들의 사원명, 급여, 부서번호를 출력하시오. (여기서 조건은 **급여를 3000이상 받는 사원이 소속된 부서** 조건절로!)
SELECT ename, sal, deptno
FROM emp
WHERE deptno IN (
                  SELECT deptno
                    FROM emp
                    WHERE sal >= 3000
                ); --20번 부서와 10번 부서의 사람들
ENAME                       SAL     DEPTNO
-------------------- ---------- ----------
FORD                       3000         20
ADAMS                      1100         20
SCOTT                      3000         20
JONES                      2975         20
SMITH                       800         20
BLAKE                                   20
MILLER                     1300         10
KING                       5000         10
CLARK                      2450         10

조건서브쿼리)
SELECT deptno
FROM emp
WHERE sal >= 3000;

    DEPTNO
----------
        20
        10
        20

--===========================================================================

문제)
부서번호가 30번인 사원들 중 급여를 가장 많이 받는 사원보다 더 많은 급여를 받는 사원의 사원명, 급여를 출력.
(ALL 다중 행 연산자 사용!!)

조건서브쿼리)
SELECT SAL
FROM EMP
WHERE DEPTNO = 30;

결과)
       SAL
----------
      1600
      1250
      1250
      2850
      1500
       950

SELECT ename, sal
FROM emp
WHERE sal > 
            (
               SELECT SAL
                FROM EMP
                WHERE DEPTNO = 30
            ); --에러 발생!

SELECT ename, sal
FROM emp
WHERE sal > ALL --ALL을 쓰자!
            (
               SELECT SAL
                FROM EMP
                WHERE DEPTNO = 30
            );

SELECT ename, sal
FROM emp
WHERE sal > 
            (
               SELECT MAX(SAL) -- MAX 쓰면 ALL안써도 된다, 하지만 위에서 연습겸 ALL을 사용한 것.
                FROM EMP
                WHERE DEPTNO = 30
            );

결과)
ENAME                       SAL
-------------------- ----------
JONES                      2975
FORD                       3000
SCOTT                      3000
KING                       5000

--===========================================================================

문제) 부서번호가 30번인 사원들 중 급여를 가장 많이 적게 사원보다 더 많은 급여를 받는 사원의 사원명, 급여를 출력(ANY 다중 행 연산자 사용!)

SELECT ename, sal
FROM EMP
WHERE sal  >
         (
            SELECT sal --1600, 1250, 1250, 2850, 1500, 950 들어옴
            FROM emp
            WHERE deptno = 30
          );

ORA-01427: single-row subquery returns more than one row -- 에러발생

SELECT ename, sal
FROM EMP
WHERE sal  > ALL --모든 데이터중 가장 큰 값
         (
            SELECT sal --1600, 1250, 1250, 2850, 1500, 950 들어옴
            FROM emp
            WHERE deptno = 30
          );
ENAME                       SAL
-------------------- ----------
JONES                      2975
FORD                       3000
SCOTT                      3000
KING                       5000

SELECT ename, sal
FROM EMP
WHERE sal  > ANY --모든 데이터중 가장 큰 값, 각 항목보다 커도 좋고(1600보다, 1250보다...)
         (
            SELECT sal --1600, 1250, 1250, 2850, 1500, 950 들어옴
            FROM emp
            WHERE deptno = 30
          );

ENAME                       SAL
-------------------- ----------
KING                       5000
FORD                       3000
SCOTT                      3000
JONES                      2975
BLAKE                      2850
CLARK                      2450
ALLEN                      1600
TURNER                     1500
MILLER                     1300
WARD                       1250
MARTIN                     1250
ADAMS                      1100

문제 해답
SELECT ename, sal
FROM EMP
WHERE sal  > --모든 데이터중 가장 큰 값, 각 항목보다 커도 좋고(1600보다, 1250보다...)
         (
            SELECT min(sal) --1600, 1250, 1250, 2850, 1500, 950 들어옴
            FROM emp
            WHERE deptno = 30
          );

ENAME                       SAL
-------------------- ----------
ALLEN                      1600
WARD                       1250
JONES                      2975
MARTIN                     1250
BLAKE                      2850
CLARK                      2450
SCOTT                      3000
KING                       5000
TURNER                     1500
ADAMS                      1100
FORD                       3000
MILLER                     1300

--===========================================================================

문제1)

SCOTT과 급여가 동일하거나 더 많이 받는 사원의 이름과 급여 출력
SELECT ename, sal
FROM emp
WHERE sal >= any ( --SCOTT가 하나 있으면 >= 도 관계 없지만, 중복되면 any등으로 사용해야 한다.
                SELECT sal
                FROM emp
                WHERE ename = 'SCOTT'
            );

ENAME                       SAL
-------------------- ----------
SCOTT                      3000
KING                       5000
FORD                       3000

--추가
SELECT ename, sal
FROM emp
WHERE sal >= all ( --SCOTT가 하나 있으면 >= 도 관계 없지만, 중복되면 any등으로 사용해야 한다.
                SELECT sal
                FROM emp
                WHERE ename = 'SCOTT'
            );
--===========================================================================

문제2)
직급(job)이 사원(CLERK)인 사람이 속한 부서의 부서번호와 부서명, 부서위치를 출력.
SELECT dname, loc
FROM dept
WHERE deptno IN (
                SELECT deptno
                FROM emp
                WHERE job = 'CLERK' 
            );

DNAME                        LOC
---------------------------- --------------------------
ACCOUNTING                   NEW YORK
RESEARCH                     DALLAS
SALES                        CHICAGO

--===========================================================================

문제3)
사원명에 'T'를 포함하고 있는 사원들과 같은 부서에서 근무하고 있는 사원의 사원번호 이름을 출력.
SELECT empno, ename
FROM emp
WHERE deptno IN ( -- = 을 쓴다면 모두 만족해야 하는 것, IN을 써야 한다.
                SELECT deptno
                FROM emp
                WHERE ename like '%T%'
              );

     EMPNO ENAME
---------- --------------------
      7902 FORD
      7876 ADAMS
      7788 SCOTT
      7566 JONES
      7369 SMITH
      8000 BLAKE
      7900 JAMES
      7844 TURNER
      7698 BLAKE
      7654 MARTIN
      7521 WARD
      7499 ALLEN
--===========================================================================

문제4) 부서위치가 NEW YORK인 모든 사원의 이름, 부서번호를 출력

SELECT ename, deptno
FROM emp
WHERE deptno IN ( --NEW YORK이 또 생길 수도 있잖아. 지사라던가... 그래서 IN을 쓰는것이 좋다.
                   SELECT deptno
                    FROM dept
                    WHERE loc = 'NEW YORK'
                  );

ENAME                    DEPTNO
-------------------- ----------
CLARK                        10
KING                         10
MILLER                       10

--===========================================================================

문제5) SALES부서의 모든 사원의 이름과 급여출력

SELECT ename, sal
FROM emp
WHERE deptno = 
               (
                   SELECT deptno
                   FROM dept
                   WHERE dname = 'SALES'
                );

ENAME                       SAL
-------------------- ----------
ALLEN                      1600
WARD                       1250
MARTIN                     1250
BLAKE                      2850
TURNER                     1500
JAMES                       950

--===========================================================================

문제6) KING에게 보고하는 모든 사원의 이름과 급여를 출력

SELECT ename, sal
FROM emp
WHERE mgr IN
            (
                SELECT empno
                FROM emp
                WHERE ename = 'KING'
             );

ENAME                       SAL
-------------------- ----------
JONES                      2975
BLAKE                      2850
CLARK                      2450

--===========================================================================

문제7) 자신의 급여가 평균 급여보다 많고  이름에 'S'가 들어가는 사원과
      ------------------------ ----------
                (1번째 조건)      (2번째 조건)
                ---> 1,2번을 동시에 만족하는 사원의 부서

       동일한 부서에서 근무하는 모든 사원의 사원번호, 사원명, 급여 출력.

SELECT empno, ename, sal
FROM emp
WHERE deptno IN -- IN 은 = 과 같음 (거으...의?), 여기서는 IN 또는 ANY 또는 ALL이 나와야 한다!
            (
                SELECT deptno
                FROM emp
                WHERE ename like '%S%'
                        and
                sal > (SELECT AVG(sal) FROM emp)
              );

     EMPNO ENAME                       SAL
---------- -------------------- ----------
      7902 FORD                       3000
      7876 ADAMS                      1100
      7788 SCOTT                      3000
      7566 JONES                      2975
      7369 SMITH                       800
      8000 BLAKE

-- WHERE 그룹함수() => 에러
-- WHERE sal > avg(sal) 이러면 에러 
-- 정상실행 위해서는 서브쿼리로 !
-- WHERE sal > ( SELECT avg( sal )
--                FROM emp)  => 정상실행

-- HAVING 그룹함수() => 정상실행
-- HAVING avg(sal) > 2000 => 정상실행
-- HAVING deptno = 10 => 정상실행 왜? 그룹 중 10번 부서만!!
-- HAVING sal > 2000 => 에러? 왜? 10번부서에는 sal속성이 없기 때문에

<DDL.> Data Definition Language : (객체)데이터 정의어

  • 객체 : TABLE, VIEW, SEQUENCE, TRIGGER

  • create, drop, alter, rename, truncate

  • DDL은 AUTO 커밋!

<테이블(객체) 생성>

형식)

CREATE TABLE 테이블명
(
    컬럼명1 자료형,
    컬럼명2 자료형,
    컬럼명3 자료형
);

<자료형> 데이터 : 문자, 숫자, 날짜, 이미지등

  • CHAR : 주어진 크기만큼 고정길이의 문자 저장 1바이트 ~ 2000바이트
pName char(10)
gildong입력 ---> '    gildong' 이 입력됨 ( 앞에 공백)
  • VARCHAR2 : 주어진 크기만큼 가변길이의 문자 저장 1바이트 ~ 4000바이트
pName varchar2(10)
gildong입력 ---> 'gildong' 입력!
  • NUMBER(p[,s]) : 정밀도와 스케일로 표현되는 숫자
    • 바이트 수 생략 가능
number(7,2) --전체 자릿수 7, 소숫점 이하 2자리까지 표현, 정수는 5자리까지!
--예) no number( 7, 2 ) => 12345.67
--입력 ==>12345 ( O )
--입력 ==>99999 ( O )
--입력 ==>123456 ( X ) 
--입력 ==>12345.678 ( O ), 입력은 된다, 하지만 저장은 12345.68(올림처리)
--입력 ==>99999.99 ( O )
--입력 ==>99999.992 ( O )
--입력 ==>99999.995 ( X ), 저장 100000.00이기때문에
pName varchar2(10) -- ( O )
pName varchar2 -- ( X )
pAge number(10) -- ( O )
pAge number -- ( O )
  • DATE : 날짜 형식 저장
  • TIMESTAMP : DATE형의 확장된 형태
  • BLOB : 대용량의 바이너리 데이터를 저장, 최대 4GB
  • CLOB : 대용량의 텍스트 데이터를 저장, 최대 4GB
  • BFILE : 대용량의 바이너리 데이터를 파일형태로 저장, 최대 4GB

CREATE TABLE emp
( );
--ORA-00904: : invalid identifier --에러발생, 이클립스에도 이런식으로 뜬다면 DB의 문제라는것을 파악해야 한다.
--테이블을 생성하기 위해서는 최소 한 개 이상의 컬럼을 정의해야 함!

--===========================================================================

CREATE TABLE emp
(
    empno number(4)
);
--ORA-00955: name is already used by an existing object --에러 발생
-- 이미 존재하는 테이블명(객체명)과 같은 이름은 생성 불가!

--===========================================================================

CREATE TABLE 2emp
(
    empno number(4)
);
--ORA-00903: invalid table name --에러발생. 부적절한 테이블(식별자)명
-- 식별자 이름규칙이 있다!
-- 첫글자 숫자불가, 예약어불가, 특수문자 불가

--===========================================================================

CREATE TABLE emp2
(
    empno number(4)
);
--Table created.
--===========================================================================
SQL> select tname from tab;
TNAME
------------------------------------------------------------
DEPT
EMP
EMP2
SALGRADE
--임포트한 테이블 조회 가능

--===========================================================================

CREATE TABLE emp2
(
    empno number(4)
    ename VARCHAR(4)
    sal number(7,2)
);
--ORA-00907: missing right parenthesis -- 에러발생
--두 개 이상의 컬럼을 정의할 때 그 구분을 위해 ','(콤마)를 사용!

CREATE TABLE emp3
(
    empno number(4),
    ename VARCHAR(4),
    sal number(7,2)
);
--Table created. -- 생성 완료!

SELECT * FROM emp2;
SELECT * FROM emp3;
--no rows selected --조회결과 없음

<서브쿼리를 이용한 테이블 생성>

  • 기존 테이블의 구조( 컬럼, 자료형 )와 (행) 데이터를 복사

  • 제약(constraint)은 복사에서 제외

  • 형식

    CREATE TABLE 테이블명
    AS 서브쿼리;
    
    create table emp4
    as select * from emp; --select는 열제어 *(와일드카드)는 모든 행
    --Table created. 메시지
    
    desc emp4;
    desc emp;
    --NULL? 은 NULL허용 여부
    
    SQL> select count(*) from emp3;
    
      COUNT(*)
    ----------
             0
    
    SQL> select count(*) from emp4;
    
      COUNT(*)
    ----------
            15
    
    SELECT empno, ename, sal
    FROM emp4;
         EMPNO ENAME                       SAL
    ---------- -------------------- ----------
          8000 BLAKE
          7369 SMITH                       800
          7499 ALLEN                      1600
          7521 WARD                       1250
          7566 JONES                      2975
          7654 MARTIN                     1250
          7698 BLAKE                      2850
          7782 CLARK                      2450
          7788 SCOTT                      3000
          7839 KING                       5000
          7844 TURNER                     1500
          7876 ADAMS                      1100
          7900 JAMES                       950
          7902 FORD                       3000
          7934 MILLER                     1300
궁금상자
1. 다중행연산자 이해가 안된다. (IN, ANY, SOME, ALL, EXISTS)
- IN은 OR OR OR... =과 같으나 =보다는 IN을 쓰는것이 좋다. 중복된 값이 있을때에는 = 쓰면 에러가 발생한다. 
- ANY랑 SOME은 같은 의미로 사용되는듯 ?
- ALL과 ANY는 아래의 표 참조
- EXISTS는 서브쿼리 값 있으면 반환

2. 서브쿼리는 SELECT문 내의 또다른 SELECT문 정도?, 데이터 가공 위해, 선생님의 수업시간 설명 참조. SELECT INSERT UPDATE DELETE 에서 사용 SELECT리스트 FROM절 WHERE절에도 조건에 따라 사용 가능

3. CHAR VARCHAR VARCHAR2
아래 표 참조
 VARCHAR와 VARCHAR2차이 없으나, 오라클에서는 VARCHAR2 사용 권장, 오라클에서 VARCHAR 타입은 추후 다른 용도로 사용한다고 함
     
컬럼 > ANY 가장 작은 값보다 크다, ? > MIN
컬럼 < ANY 가장 큰 값보다 작다, ? <MAX
컬럼 > ALL 가장 큰 값보다 크다, 최대값 반환 > MAX
컬럼 < ALL 가장 작은 값보다 작다, 최소값 반환 < MIN
CHAR VARCHAR VARCHAR2
고정형 가변형 가변형
2000byte 4000byte4 000byte

사일째

 

240p 짜리 요약집 중 1과목 정독

(한번 더 빠르게

 

 

아침 유튜브 강의 30분 봄

수업후 30분 요약집 공부

집가면서 안볼 예정

집에서 공부 120분 할 예정

'SQLD' 카테고리의 다른 글

190530 SQLD 공부-6  (0) 2019.05.30
190529 SQLD 공부-5  (0) 2019.05.29
190523 SQL 공부-3  (0) 2019.05.23
190522 SQL 공부-2  (0) 2019.05.22
190521 SQL 공부  (0) 2019.05.21

190527_DAY33 decode, case , join


Structured Query Language

  1. DQL(데이터 조회,검색,출력)

    • select

    DQL문법)

    1. select 컬럼명
    2. from   테이블명
    3. where  조건식
    4. group by 컬럼명
    5. having  조건식
    6. order by  컬럼명;

    실행순서) 2- 3- 4- 5- 1(DB로 부터의 조회,인출)- 6 - 1(정렬된 결과를 출력)

     select distinct 조회컬럼명1 [as] 별명, 컬럼명2  || 컬럼명3,  데이터, 산술연산, 
                        함수호출(예: length(ename)), 그룹함수호출(count(),sum(),max(),min(),avg())
    
     from   테이블명
     where  조건식
            ---------
                      컬럼명       연산자       데이터
                  -------
                                   비교연산자(>  <   >=   <=  =   !=  ^=  <>)
                  like      '패턴%_'
                  in        (value_list)  
    
              예) deptno  in        (10,20,30)
           ==> deptno = 10  OR  deptno = 20  OR  deptno = 30      
          ename   in        ('ADAMS','MILLER')
           ==> ename = 'ADAMS'  OR  ename = 'MILLER'
    
                  between  최소값 and 최대값
             예) sal >= 2000  and  sal<=3000                     
           sal    between  2000 and  3000           ==> 2000이상~ 3000이하
           sal    not between  2000 and  3000       ==> 2000미만, 3000초과
      not  sal    between  2000 and  3000           ==> 2000미만, 3000초과
    
                    =      null    (실행결과 없음)
                    is     null    (컬럼의 값이 null과 같다면)
                    is  not null    (컬럼의 값이 null과 같지않다면)
    <부정연산자>                                                        
     not 조건식
     not (조건식1 or 조건식2)
     not in
     not like
     not between 최소값 and 최대값                                                                         
    
     group by (그룹묶을수 있는)컬럼명
                 예)  group by  deptno
              ===> (10번부서의 사원들)   (20번부서의 사원들) (30번부서의 사원들)
    
     having  (그룹에 대한) 조건식
             ===> group by와 반드시 함께 사용!!
             ===> deptno = 10            : 3개의 그룹중 (10번부서의 사원들만)
                  avg(sal) >= 2000       : 10번,20번,30번 부서 각각의 평균 급여를 비교
                                          ---- ---- ----      
                                    (사원3명 급여 더하기/3)                                                  
                                        (사원5명 급여 더하기/5)     
                                              (사원6명 급여 더하기/6)
     order by  (정렬할 )컬럼명  [ASC|DESC];
                            ----------
                                         생략하면 ASC(오름차순) 기본값
    
                              컬럼명1, 컬럼명2
               ------ -------
               1차정렬    1차정렬결과에 대한 2차정렬
  2. DML(데이터 조작 - 추가, 수정, 삭제)

    • insert , update , delete
  3. DDL(데이터[객체-table,view,sequence,trigger] 정의) : Auto Commit

    • create, alter, drop, rename, truncate

      emp테이블명 ----> employee테이블명

           구조변경(컬럼수 변경-emp테이블에 email컬럼을 추가
                 -ename 15byte를 30byte로 변경)
  4. DCL

    • DB관리자가 일반사용자에게 권한 부여, 권한 회수
      -------  -------
      grant     revoke
  5. TCL

    • 논리적인 (DML)작업단위: Transaction

    • DB에 물리적인 반영, 논리 작업 전체 취소, 부분 작업 취소

      commit rollback savepoint(저장점)


DECODE 함수

  • 형식

    DECODE(컬럼명, 
            비교데이터1, 결과데이터1
            비교데이터2, 결과데이터2......)
    • 사원들의 사원번호(empno), 사원명(ename), 부서번호(deptno), 부서명(dname)을 출력하시오

      •  select empno, ename, deptno, decode(deptno,
                                                    10, 'ACCOUNTING',
                                                    20, 'RESEARCH',
                                                    30, 'SALES',
                                                    40, 'OPERATIONS') 부서명 
         from   emp;
        
           EMPNO ENAME                    DEPTNO 부서명

        7369 SMITH                        20 RESEARCH
        7499 ALLEN                        30 SALES
        7521 WARD                         30 SALES
        7566 JONES                        20 RESEARCH
        7654 MARTIN                       30 SALES
        7698 BLAKE                        30 SALES
        7782 CLARK                        10 ACCOUNTING
        7788 SCOTT                        20 RESEARCH
        7839 KING                         10 ACCOUNTING
    • 문제) 사원들의 사원번호(empno), 사원명(ename), 부서번호(deptno), 부서명(dname),

           사원번호에 대한 홀수 또는 짝수를 출력하시오
       ==> decode함수 사용!!    
      •    select empno, ename, deptno, decode(deptno,
                                                      10, 'ACCOUNTING',
                                                      20, 'RESEARCH',
                                                      30, 'SALES',
                                                      40, 'OPERATIONS') 부서명, 
                                         decode( mod( empno,2 ),
                                                      0, '짝수',
                                                      1, '홀수') 홀짝
           from   emp;
        
                EMPNO ENAME                    DEPTNO 부서명               홀짝
        ---------- -------------------- ---------- -------------------- ------------
              7369 SMITH                        20 RESEARCH             홀수
              7499 ALLEN                        30 SALES                홀수
              7521 WARD                         30 SALES                홀수
              7566 JONES                        20 RESEARCH             짝수
              7654 MARTIN                       30 SALES                짝수
              7698 BLAKE                        30 SALES                짝수
              7782 CLARK                        10 ACCOUNTING           짝수
              7788 SCOTT                        20 RESEARCH             짝수
              7839 KING                         10 ACCOUNTING           홀수
              7844 TURNER                       30 SALES                짝수
              7876 ADAMS                        20 RESEARCH             짝수
              7900 JAMES                        30 SALES                짝수
              7902 FORD                         20 RESEARCH             짝수
              7934 MILLER                       10 ACCOUNTING           짝수

<CASE함수>

  • 형식

    CASE WHEN 조건식1 THEN 결과데이터1
        WHEN 조건식2 THEN 결과데이터2
        WHEN 조건식3 THEN 결과데이터3
        ELSE 결과데이터n
    END
  • 문제

    사원들의 사원번호(empno), 사원명(ename), 부서번호(deptno), 부서명(dname), 사원번호
    에 대한 홀수 또는 짝수를 출력하시오
    => CASE문 사용
    
    SELECT     empno, ename, deptno, 
        CASE
            WHEN deptno = 10 then 'ACCOUNTING'
            WHEN deptno = 20 then 'RESEARCH'
            WHEN deptno = 30 then 'SALES'
            WHEN deptno = 40 then 'OPERATIONS'
            ELSE 'OPERATIONS'
            END "부서명",
            CASE
                WHEN mod(empno, 2) = 0 then '짝수사원번호'
                ELSE '홀수사원번호'
            END "짝홀"    
    FROM EMP;

★<조인> JOIN

  • 한개 이상의 테이블에서 데이터를 조회하기 위해 사용

  • 두개 이상의 테이블을 참조해서 데이터를 검색

  • from 뒤에 두 개 이상의 테이블을 명시

  • 예)

    • FROM emp, dept
    • FROM emp,emp
  • 문제)

    SCOTT 사원이 근무하는 부서의 부서번호와 부서명, 부서위치를 출력하시오.
    
    SELECT deptno, dname, loc
    FROM emp
    WHERE ename = 'SCOTT'; 
    
    SELECT deptno, dname, loc
    FROM dept
    WHERE deptno = 20;
    
    => SCOTT사원이 근무하는 부서명은 'RESEARCH' 이고 'DALLAS'에 위치하고 있습니다.
    이건 하나로 합쳐서!
    
    SELECT ename, dname 
    FROM emp, dept;
    // 14행 8열 * 14행 3열 = 56행 11열
    // 결과행 : 56행 , 특정한 조건을 주지 않는다면 조인시 각 테이블이 갖는 행의 수를 곱한 형태의 결과가 출력
    
    from emp,edpt,salgrade; 
    로 하면 14 *4 * 5
    
    select ename, deptno, dname, loc
    from emp, dept;
    
    //ORA-00918: column ambiguously defined 라는 에러 발생, emp와 dept가 공통적으로 deptno를 갖고 있기 때문
    
        select emp.ename, emp.deptno, dept.dname, dept.loc
        from       emp,          dept;
    
        select ename, emp.deptno, dname, loc
        from       emp,          dept;
        ==> 56행 4열 출력   
           -----
           사원1명 과   부서4개행을 매핑
    
    
  select ename, emp.deptno, dname, loc
  from       emp,          dept
  where  emp.deptno  =  dept.deptno;
  ==>  14행 4열 출력
       ---- 
     사원1명 과   부서 1개행을 매핑

  select ename, emp.deptno, dname, loc
  from       emp,          dept
  where  ename = 'SCOTT'
         and
         emp.deptno  =  dept.deptno;

문제) MILLER사원이 근무하는 부서정보를 아래와 같이 출력하시오.
==> MILLER사원은 10번 부서에 근무하고 부서명은 ACCOUNTING이고 위치는 NEW YORK입니다.
select ename, emp.deptno, dname, loc
from emp, dept
where ename = 'MILLER'
and
dept.loc = 'NEW YORK';


  <EQUI JOIN>

  - 조인 대상이 되는 두 테이블에서 공통적으로 존재하는 컬럼의 값이
    일치하는 행을 연결하여 결과를 생성하는 조인.

  ※ 참고 : select * from emp,dept;
    ===> 특별한 조건없이 두 테이블을 곱(14행 * 4행)의 형태로 출력: CROSS JOIN  

  문제) 'NEW YORK'에서 근무하는 사원의 이름과 급여를 출력하시오.

  ```sql
  select ename, sal,dept.deptno, loc
  from emp, dept
  where loc = 'NEW YORK'
              and
                  emp.deptno  =  dept.deptno;
  select ename, hiredate
  from emp, dept
  where dname = 'ACCOUNTING'
  and emp.deptno = dept.deptno;

문제) ACCOUNTING부서 소속 사원들의 이름과 입사일(YYYY/MM/DD)을 출력하시오.

  select ename, hiredate, emp.deptno, DNAME
  from emp, dept
  where DNAME = 'ACCOUNTING'
              and
                  emp.deptno  =  dept.deptno;

문제) 직급이 MANAGER인 사원의 이름, 부서명을 출력하시오.

  select ename, hiredate,  JOB , emp.DEPTNO
  from emp, dept
  where JOB = 'MANAGER'
              and
                  emp.deptno  =  dept.deptno;
  • 특정 범위내에 있는 값을 조회하기 위해 (대소)비교연산자를 사용.

  • 문제

    각 사원의 사원번호, 사원명, 급여, 급여등급(1~5등급)을 출력하시오
    
     select empno, ename, sal, grade
     from   emp,  salgrade  -- 14* 5 = 70행!!
     where  sal between  losal and hisal;  -- 14행!!   -- sal >= losal and  sal <= hisal
    
    

문제) ALLEN사원의 사원번호, 사원명, 급여, 급여등급, 부서명을 출력하시오.
select empno, ename, sal, grade, dname
from emp, salgrade, dept
where ename = 'ALLEN'
and
emp.deptno = dept.deptno
and
sal between losal and hisal;


------

<SELF JOIN>

- 마치 같은 테이블이 두개인 것처럼 자기 자신의 테이블과 조인하는 것.

- 문제

SCOTT사원의 사원번호, 사원명, 급여, 직속상사명을 출력하시오
select my.empno, my.ename, my.sal, mgr.ename
from emp my, emp mgr
where my.ename = 'SCOTT'
and
my.mgr = mgr.empnil;

SCOTT사원과 동일한 근무지(부서)에서 근무하는 사람(동료사원)의 이름을 출력
select e1.ename 기준사원명, e2.ename 동료사원명
from emp e1, emp e2
where e2.ename <> 'SCOTT'
and
e1.ename = 'SCOTT'
and
e1.deptno = e2.deptno;


------

<outer Join>

- 테이블 조인 중 한쪽 테이블에 존재하지 않는 데이터로 인해서
      출력되지 않는 행을 출력하고 싶을 때 사용.

-  '(+)'기호 사용

- 문제

전체사원)각 사원의 이름과 그사원의 직속 상사이름을 출력하시오.
select e1.ename 사원명, e2.ename 직속상사명
from emp e1, emp e2
where e1.mgr = e2.empno; -- 예상 출력행의 수: 14
===> 13행 출력( 전체사원수는 14명!! ---> e1.mgr이 null인 KING사원은 배제)

각 사원의 이름과 부서번호, 부서명, 부서위치를 출력하시오
select ename, d.deptno, dname, loc
from emp e, dept d
where e.deptno = d.deptno;

14명 사원에 매핑되지 않은 부서정보(40)도 함께 출력하고 싶다.
select ename, d.deptno, dname, loc
from emp e, dept d
where e.deptno (+)= d.deptno;




<Join관련 문제>

```sql
--문제1) 사원들의 이름, 부서번호, 부서이름을 출력
select ename, emp.deptno, dept.dname
from emp, dept
where emp.deptno (+)= dept.deptno;
--문제2) 부서번호가 30번인 사원들의 이름, 직급, 부서번호, 부서위치를 출력
select ename, job, emp.deptno, dept.loc
from emp, dept
where     dept.deptno = 30
        and
        emp.deptno (+)= dept.deptno;
--문제3) 커미션을 받는 사원의 이름, 커미션, 부서이름, 부서위치 출력(커미션 0은 제외)
select ename, comm, dname, loc, emp.deptno
from emp, dept
where comm != 0
        and
        comm is not null
        and
        emp.deptno = dept.deptno;
--문제4) DALLAS에서 근무하는 사원들의 이름, 직급, 부서번호, 부서이름을 출력
select ename, job, emp.deptno, dname
from emp, dept
where loc = 'DALLAS'
        and
        emp.deptno = dept.deptno;
--문제5) 사원이름에 'A'가 들어가는(포함하는) 사원들의 이름과 부서이름을 출력
select ename, dname
from emp, dept
where ename like '%A%'
        and
        emp.deptno = dept.deptno;
--문제6) 사원이름과 직급, 급여, 급여등급을 출력
select ename, job, sal, grade
from emp, dept, salgrade
where emp.deptno = dept.deptno
        and
        sal between  losal and hisal;
--문제7) 사원들의 이름과 그 사원과 같은 부서에 근무하는 사원의 사원명, 부서번호를 출력
      --===> 자기 이름을 제회한 동료(56행) 정보 출력!!
select e2.ename "동료명", e1.ename "사원명",  e2.deptno
from emp e1, emp e2
where e2.deptno   =  e1.deptno
        and
        e1.empno ^= e2.empno;

ANSI 조인 = DBMS의 종류와 상관없이 실행되는 표준 조인

from 테이블명1, 테이블명2

-> 콤마 제거

select empno, ename, dname
from emp, dept;
---> 14행 * 4행 : 56행

select empno, ename, dname
from emp cross join dept;
---> 56행

  • 테이블 사이에 inner join사용
    동등 조건식 ON(조건절!!) 뒤에 사용
  • where절을 추가하는 것이 가능
  • on절은 반드시 추가!!
  • on절에 동등비교와 추가적인 조건식을 기술 가능.
 문제) 전체 사원에 대한 사원번호, 사원명, 부서명을 출력.
  select empno, ename, dname
  from  emp  inner join  dept;
  ---> ORA-00905: missing keyword  (on조건절을 명시!!)

    select empno, ename, dname
  from  emp  inner join  dept
  on  emp.deptno = dept.deptno;

   EMPNO ENAME                DNAME
  7782 CLARK                ACCOUNTING
  7839 KING                 ACCOUNTING
  7934 MILLER               ACCOUNTING
  7566 JONES                RESEARCH
  7902 FORD                 RESEARCH
  7876 ADAMS                RESEARCH
  7369 SMITH                RESEARCH
  7788 SCOTT                RESEARCH
  7521 WARD                 SALES
  7844 TURNER               SALES
  7499 ALLEN                SALES

  문제) JAMES사원에 대한 사원번호, 사원명, 부서명을 출력하시오.
   select empno, ename, dname
   from     emp inner join dept
   on     emp.deptno = dept.deptno -- 공통 컬럼 매핑
   where  ename='JAMES';

    EMPNO ENAME                DNAME
      7900 JAMES                SALES

<Inner Join에 USING절 사용하기>

  • 형식

    USING(공통컬럼명)
    
     select empno, ename, dname
     from   emp inner join dept
     USING  (deptno);-- 14행출력
    
    ※USING절 사용시 공통된 컬럼에 대해 emp.deptno 또는 dept.deptno 사용 불가!!
                              ---> 특정 테이블이 아닌 USING절에서 정의한 deptno컬럼명만 사용!!
     select empno, ename, emp.deptno, dname   -- 에러발생
     from   emp inner join dept
     USING  (deptno);
    
      select empno, ename, deptno, dname   -- 실행OK
     from   emp inner join dept
     USING  (deptno);

<.Natural Join>

select empno, ename, dname
from emp natural join dept; --두 테이블이 갖는 컴럼 중 공통된 이름의 컬럼을 동등조건해줌

--문제) ADAMS의 사우너번호, 사원명, 부서명을 출력
select empno, ename, dname
from emp natural join dept
where ename = 'ADAMS';

<.ANSI Outer Join>

  • 형식

    FROM 테이블명1 (LEFT | RIGHT | FULL) [OUTER] JOIN 테이블명2
    --조건절은 ON!!
    
    문제) 각 사원의 이름과 그 사원의 직속 상사이름을 출력하시오
    select e1.ename "사원명", e2.ename "직속상사명"
    from emp e1 left join emp e2
    on e1.mgr = e2.empno; --mgr에는 null 있고 empno에는 null 없다.
    
    문제) 각 사원의 이름과 부서번호, 부서명, 부서위치를 출력하시오
    (14명 사원이 속하지 않은 40번 부서에 대해서 출력)
    
    select ename, dept.deptno, dname, loc --여기서 deptno은 emp.deptno 쓰면 누락 속성 생김.
    from emp right join dept --right outer join으로 풀네임 써도 됨.
    on emp.deptno = dept.deptno; -- dept에 null값 있음
delete와 truncate, drop의 차이
- delete는 데이터를 지우는것이지 테이블 용량은 줄어들지 않는다
- truncate는 용량이 줄어들고 인덱스들도 모두 삭제, 테이블은 삭제 않고 데이터만 삭제 ( 삭제 후 되돌릴 수 없다.)
- dtop은 테이블 전체를 삭제 공간, 객체를 삭제 (삭제 후 되돌릴 수 없다.)

190524_Day32 DB3 복습,


- Structured Query Language

  1. DDL(객체정의)

    • create, drop, alter, rename, truncate
  2. DML(데이터조작)

    • insert, delete, update
  3. DCL(권한줬다뺏기)

    • grant, revoke
  4. DQL(데이터질의)

    • select

    select 컬럼명 1
    from 테이블명 2
    where 조건식 3
    order by 컬럼명; 4

    실행순서) 2 - 3 - 1(조회,인출) - 4 - 출력

    select [distinct] 컬럼명1 [as] 별명, 컬럼명2 "별명", 데이터, 산술연산, 컬럼명3 || 데이터
    from 테이블명

    where 조건식

    (컬럼명     연산자    비교데이터)
            -----

    ​ 비교연산자(< > <= >= = != ^= <> )
    ​ like '패턴%_'
    ​ in (value_list)
    ​ deptno in (10,20,30)
    ​ between 최소값 and 최대값 :최소값이상 ~ 최대값이하

     comm     =    null    (X)
     comm    !=    null    (X)
     comm    is    null     (O)
     comm    is  not  null  (O) 

    order by 컬럼명 [ASC|DESC];

    ​ 기본값
    ​ nvl(인자1,인자2)함수 : null값을 특정값으로 변환하는 기능

    인자1: null예상되는 컬럼명
    인자2: 대체할 데이터

    주의사항: 인자1과 인자2의 자료형이 같아야 함.

  5. TCL(트랜잭션제어)

    • commit, rollback, savepoint

==============================================================================
<숫자함수>

  • round함수 : 반올림(4이하는 버리고 5이상은 올림)

  • 형식)

    round(기준데이터)
    round(기준데이터, 소수점이하 자리수 표현)
    
    select round(45.56) from dual;
    ===
    SQL> select round(45.573, 2) 라운드 from dual;
    
        라운드
    ----------
         45.57
    ===
    SQL> select round(45.575, 2) 라운드 from dual;
    
        라운드
    ----------
         45.58
    
  • TRUNC 함수 : 버림함수

    select trunc(45.56) from dual;
    
    SQL> select trunc(45.56) from dual;
    
    TRUNC(45.56)
    ------------
              45
    
    ===
    SQL> select trunc(45.56, 1) from dual;
    
    TRUNC(45.56,1)
    --------------
              45.5
    
  • FLOOR 함수 : 소수점 이하 버림함수

    SQL> select floor(45.56) from dual;
    
    FLOOR(45.56)
    ------------
              45
    
    ===
    SQL> select floor(45.568 2) from dual;
    SP2-0734: unknown command beginning "SQL> selec..." - rest of line ignored.
    
    //소수점 2자리까지만 표현해 달라는 것인데 floor에서 .56을 살릴수는 없다
  • 문제) 10/3의 몫과 나머지를 구하시오

    select floor(10/3) 몫, mod(10,3)
    from dual;
    
    ==> mod()함수를 테이블에 적용!
    예) 급여를 100으로 나누고 나머지를 구하시오
    
    select sal, mod(sal, 100)
    from emp;
  • 예) 급여를 100으로 나누고 나머지를 구하시오.

    select sal, mod(sal,100)
    from emp;     
    
           SAL MOD(SAL,100)
    ---------- ------------
           800            0
          1600            0
          1250           50
          2975           75
          1250           50
          2850           50
          2450           50
          3000            0
          5000            0
          1500            0         
  • 문제) 사원번호가 짝수인 사원의 사원번호, 사원명을 출력하시오

    select empno, ename
    from emp
    where empno%2 = 0; //에러
    
    select empno, ename
    from emp
    where mod(empno,2) = 0;
    
         숫자%2 == 0  ==> 짝수   
         숫자%2 != 0  ==> 홀수   
         숫자%2 == 1  ==> 홀수   

<문자함수>

  • UPPER함수 : 대문자 변환 함수

    select upper('welcome to oracle') from dual;
    UPPER('WELCOMETOORACLE')
    ----------------------------------
    WELCOME TO ORACLE
    
    ===
    select upper('welcome to oracle') from dual;
    INITCAP('WELCOMETOORACLE')
    ----------------------------------
    Welcome To Oracle
  • 문제) 30번 부서의 사우너명과 사우너번호를 출력하시오

  • (단, 사원명의 첫글자만 대문자로 출력)

      select initcap(ename) ename, empno
      from   emp
      where  deptno = 30;     
    
    ENAME                     EMPNO
    -------------------- ----------
    Allen                      7499
    Ward                       7521
    Martin                     7654
    Blake                      7698
    Turner                     7844
    James                      7900
  • LENGTH함수 : 문자열 길이(문자갯수)

    • select length('OracleSQL') from dual;
      ==> 9
    • select length('나길동') from dual;
      ==> 3
    • select lengthb('OracleSQL') from dual;
      ==> 9
    • select lengthb('나길동') from dual;
      ==> 9 (한글 3개문자 * 3byte)
      ==> lengthB( ) : 바이트 수 표현
  • INSTR함수 : 특정문자가 출현하는 위치를 얻어오는 함수 (자바의 indexOf('a'))

  • 형식)

    instr(기준데이터, 특정문자)
    instr(기준데이터, 특정문자, 시작인덱스, 출현횟수)
    
    ===
    
    select instr('welcome to oracle', 'o') //첫번째 o
    from dual;
    ==> 5
    
    ===
    
    데이터 : 'welcome to oracle'
    인덱스 :  1234567890123456
    
    select instr('welcome to orale', 'o' , 1, 2)    -- 두번째 'o'
    from dual;
    ==>10
  • SUBSTR : 문자열 일부분 추출, 부분 문자열 얻기

    • 형식)

      substr( 기준문자열, 시작인덱스, 부분문자열 갯수 )
      
      select substr('welcome to oracle', 12, 6)
      from dual; // 12번째 문자부터 6개의 문자 얻어오기
  • - LPAD : 오른쪽 정렬 후 왼쪽 공백에 특정 문자 채우기.
      형식)
         lpad(기준문자열, 전체길이, 채울문자)
    
      select lpad('oracle',  10,  '#') lpad from dual;     
    LPAD
    --------------------
    ####oracle     
    
    - RPAD : 왼쪽 정렬 후 오른쪽 공백에 특정 문자 채우기.
      형식)
         rpad(기준문자열, 전체길이, 채울문자)
    
       select rpad('oracle', 10, '♥') rpad from dual;
    
    RPAD
    ------------------------------------
    oracle♥♥♥♥     
    
    - LTRIM: 왼쪽 (연속된)공백 또는 (연속된)특정문자 제거
    
      문자열 :  '    oracle   '   앞에 4개의 공백, 뒤에 3개의 공백
     select ltrim('    oracle   ') ltrim from dual;
    
    LTRIM
    ------------------
    oracle
    
      select length('    oracle   ') from dual; 
      ==> 13
    
      select length(ltrim('    oracle   ')) from dual; 
      ==> 9
    
    - RTRIM: 오른쪽 (연속된)공백 또는 (연속된)특정문자 제거
    
      문자열 :  '    oracle   '   앞에 4개의 공백, 뒤에 3개의 공백
     select rtrim('    oracle   ') rtrim from dual;
    
    RTRIM
    --------------------
        oracle 
    
     select length(rtrim('    oracle   ')) "오른쪽공백제거" from dual;
     ===> 10
    
      select rtrim('oracleaaaaaaaaaaaaaaa', 'a') rtrim from dual;
    
    RTRIM
    ------------
    oracle
    
    - TRIM함수: 좌우의 연속된 공백을 제거해 주는 함수
       select length(trim('    oracle   ')) from dual;
       ===> 6
    
    문제) 사원번호와 사원명, 입사일을 출력하되 입사일은 년도만 출력하시오.
       (예: '80/12/17'  ----> '80') 

<날짜함수>

  • SYSDATE ★ : 현재 날짜 구하기

    select sysdate 현재날짜 from dual;
    현재날짜
    --------
    19/05/24
    
    문제) 내일 날짜를 구하시오.
       select sysdate+1 내일날짜, sysdate-1 어제날짜, sysdate+7 "일주일 후"
       from dual;
    
    내일날짜         어제날짜       일주일
    -------- -------- --------
    19/05/25 19/05/23 19/05/31
    
    - MONTHS_BETWEEN함수: 날짜와 날짜사이의 개월을 계산해 주는 함수
    
      형식)
       MONTHS_BETWEEN(큰DATE, 작은DATE)
    
    문제) 각 사원의 사원명, 입사일, 현재까지 근무한 개월 수를 출력하시오. 
    select ename, hiredate, floor(months_between(sysdate, hiredate)) 근무개월수,hiredate, floor(months_between(sysdate, hiredate)/12) 근무년수
    from emp;
    
    ENAME                HIREDATE 근무개월수 HIREDATE   근무년수
    -------------------- -------- ---------- -------- ----------
    SMITH                80/12/17        461 80/12/17         38
    ALLEN                81/02/20        459 81/02/20         38
    WARD                 81/02/22        459 81/02/22         38
    JONES                81/04/02        457 81/04/02         38
    MARTIN               81/09/28        451 81/09/28         37
    BLAKE                81/05/01        456 81/05/01         38
    CLARK                81/06/09        455 81/06/09         37
    SCOTT                87/04/19        385 87/04/19         32
    KING                 81/11/17        450 81/11/17         37
    TURNER               81/09/08        452 81/09/08         37
    ADAMS                87/05/23        384 87/05/23         32
    JAMES                81/12/03        449 81/12/03         37
    FORD                 81/12/03        449 81/12/03         37
    MILLER               82/01/23        448 82/01/23         37
    
    문제) 우리 클래스가 개강한 이 후 현재까지의 달수를 출력하시오
    select months_between(sysdate, '2019/04/08') from dual;
    
    MONTHS_BETWEEN(SYSDATE,'2019/04/08')
    ------------------------------------
                              1.53304585
    
    ADD_MONTHS : 특정날짜에 개월을 더한 날짜 계산
    select sysdate 오늘날짜, add_months(sysdate, 1) 한달후 from dual;
    
    ===
    
    오늘날짜 한달후
    -------- --------
    19/05/24 19/06/24
    
    ===
    
    select add_months('2019/02/28',1) 한달후 from dual;
    
    한달후
    --------
    19/03/31
    
    ===
    
    select add_months('2019/02/28',-1) 한달전 from dual;
    
    한달전
    --------
    19/01/31
    
    • LAST_DAY : 월의 마지막 날짜를 계산

      select last_day(sysdate) "lastDay" from dual;
      
      lastDay
      --------
      19/05/31
      
      ===
      
      문제) 다음 달의 마지막 날짜는?
      ==> 다음달의 마지막 날짜는 6월 30일 입니다.
      
      select '다음달의 마지막 날짜는' ||
      substr(last_day(add_months(sysdate,1)), 4, 2 ) || 
      '월' || substr(last_day(add_months(sysdate,1)),7,2) || 
      '일  입니다.' "날짜 정보"
      from dual;
      
      날짜 정보
      ------------------------------
      다음달의 마지막 날짜는06월30일  입니다.
      
      
      
```
  • NEXT_DAY : 특정날짜 후의 첫 요일의 날짜를 계산

    문제) 다음 주 월요일의 날짜?
    select next_day(sysdate, '월') from dual; //오늘을 제외한 조건에 맡는 가장 근접한 날짜
    
    NEXT_DAY
    --------
    19/05/27
    
    ===
    
    문제) 사원들이 입사한 달의 마지막 날짜를 출력하시오.
    select ename, hiredate, last_day(hiredate) from emp;
    
    ENAME                HIREDATE LAST_DAY
    -------------------- -------- --------
    SMITH                80/12/17 80/12/31
    ALLEN                81/02/20 81/02/28
    WARD                 81/02/22 81/02/28
    JONES                81/04/02 81/04/30
    MARTIN               81/09/28 81/09/30
    BLAKE                81/05/01 81/05/31
    CLARK                81/06/09 81/06/30
    SCOTT                87/04/19 87/04/30
    KING                 81/11/17 81/11/30
    TURNER               81/09/08 81/09/30
    ADAMS                87/05/23 87/05/31
    JAMES                81/12/03 81/12/31
    FORD                 81/12/03 81/12/31
    MILLER               82/01/23 82/01/31

<형변환함수>

  •     TO_CHAR                        TO_CHAR
     ----------------->         <--------------------
    NUMBER                  CHARACTER                     DATE      
         <------------------         --------------------->
             TO_NUMBER                     TO_DATE
    
    형식)  TO_CHAR (  number|date  )
          TO_CHAR (  number|date  ,   'format')
    
    포맷형식)
          YYYY(년도 4자리)   YY(년도 2자리),
          MM(월), DD(일),  DAY 또는 DY(요일),
          HH,HH12(1~12)    HH24(0~23)
          MI(분), SS(초)  
    오늘 날짜를 출력하시오
    select sysdate "오늘날짜" from dual;
    
    오늘날짜
    --------
    19/05/24
    
    ===
    
    SQL> select to_char(sysdate, 'YYYY') "오늘날짜" from dual;
    
    오늘날짜
    --------
    2019
    
    ===
    
    select to_char(sysdate, 'YYYY/mm/dd') "오늘날짜" from dual;
    
    오늘날짜
    --------------------
    2019/05/24
    
    ===
    
    문제) 오늘 날짜를 '2019년 05월 24일' 형태로 출력하시오
    
    select to_char(sysdate,'yyyy')||
    '년'||
    to_char(sysdate,'mm')||
    '월'||
    to_char(sysdate,'dd')||
    '일'
    from dual;
    
    혹은 
    
    select to_char(sysdate, 'yyyy"년"mm"월"dd"일') "오늘날짜" from dual;
    
    오늘날짜
    ----------------------------------
    2019년05월24일
    
    ===
    
    문제) 오늘 날짜를 '2019년 05월 24일 13시 12분 30초 (금요일)' 형태로 출력하시오
    
    select to_char(sysdate, ' yyyy"년" mm"월" dd"일" hh"시" mm"분" ss"초" (DaY) ') "오늘날짜" 
    from dual;
    오늘날짜
    ----------------------------------------------------------------------------------------------------
     2019년 05월 24일 01시 05분 50초 (금요일)
    
     문제) 오늘 날짜에서 2019년 4월 8일을 빼시오
        select sysdate - 2019/04/08
       from dual;
    
    SYSDATE-
    --------
    19/03/22
    
       select sysdate - '2019/04/08'
       from dual;
    
    ==> 에러: ORA-01722: invalid number
    
    형식)
         TO_DATE(문자 [,'포맷'])
    
         select sysdate - to_date('2019/04/08')
         from dual;
    
         select sysdate - to_date('2019/04/08',  'yyyy/mm/dd')
         from dual;
    
    SYSDATE-TO_DATE('2019/04/08')
    -----------------------------
                       46.6133333
    
    =========================================================================
    <논리연산자>
    - AND : 두조건 모두 만족하는 검색
    
      a,b,c,d : 숫자저장 컬럼(number) 3, 5 , 7, 9
      where  a>b  AND  c<d
            <------------------
              sql문 실행순서!!
    
      ----> c<d 비교연산을 할까? 정답: 한다!!
      ----> 이유: sql에서는 뒤에서 부터 조건식을 검사하기 때문!!
    
    문제) 10번 부서에 근무하고 직책이 CLERK인 사원의 사원번호, 사원명, 부서번호, 직책을 출력.
    select empno, ename, deptno, job
    from emp
    where job = 'CLERK'
    and
    deptno = 10;
    
    
   EMPNO ENAME                    DEPTNO JOB

    7934 MILLER                       10 CLERK

<OR연산자>

  • 둘 중 하나라도 만족하는 행을 검색.

    문제) 10번 부서에 근무하거나

      또는  직책이 CLERK인 사원의 사원번호, 사원명, 부서번호, 직책을 출력.

    select empno, ename, deptno, job
    from emp
    where job='CLERK' or deptno=10;

    EMPNO ENAME DEPTNO JOB


    7369 SMITH                        20 CLERK
    7782 CLARK                        10 MANAGER
    7839 KING                         10 PRESIDENT
    7876 ADAMS                        20 CLERK
    7900 JAMES                        30 CLERK
    7934 MILLER                       10 CLERK

<NOT연산자>

  • 조건에 만족하지 못하는 행을 검색.

  • 위치: 조건식 앞에 사용

     in, like, between 앞에 사용
     null앞에 사용

    문제) 30번 부서에 근무하는 사원의 정보(사원번호,사원명,부서번호,직책)를 출력하시오.
    select empno, ename, deptno, job
    from emp
    where not deptno = 30;

    문제 ) 이름에 'A'를 포함하지 않는 사원의 사원번호, 사원명, 부서번호를 출력하시오
    select empno, ename, deptno
    from emp
    where not ename like '%A%'; //혹은 where ename not like '%A%';

    문제) 급여가 1600 이상이고 3000 이하인 사원의 사원번호, 사원명, 급여를 출력.
    select empno, ename, sal
    from emp
    where sal between 1600 and 3000;

문제) 급여가 1600 미만 또는 3000 초과인 사원의 사원번호, 사원명, 급여를 출력.
select empno, ename, sal
from emp
where sal < 1600 or sal>3000;
EMPNO ENAME SAL


    7369 SMITH                       800
    7521 WARD                       1250
    7654 MARTIN                     1250
    7839 KING                       5000
    7844 TURNER                     1500
    7876 ADAMS                      1100
    7900 JAMES                       950
    7934 MILLER                     1300

혹은
select empno, ename, sal
from emp
where not (sal >= 1600 and sal <= 3000);

혹은
select empno, ename, sal
from emp
where sal not between 1600 and 3000;


- <그룹함수> ★ 집계함수

  - 전체데이터를 그룹별로 구분하여 통계적인 결과를 구하기 위해 사용.
  - 결과값은 항상 단행!!
  - 그룹함수와 단순컬럼은 함께 사용하는 것이 불가능!!
    (만약 그룹함수와 함께 사용하고자 하는 컬럼이 그룹으로 묶여질 수 있다면
     group by절과 함께 사용하는 것이 가능)
  - NULL은 결과값에서 제외    

- 종류) 
  SUM(총합), AVG(평균), COUNT(행갯수), MIN(최소값), MAX(최대값),
  STDDEV(표준편차), VARIANCE(분산)

형식)
그룹함수명(컬럼명)

문제) 사원들의 전체 급여 총합을 구하시오.
select sum(sal)
from emp;

SUM(SAL)

   29025

문제) 사원들의 평균 급여를 구하시오.
select avg(sal)
from emp;

AVG(SAL)

2073.21429

문제) 전체 사원들 중 가장 적은 급여와 가장 많은 급여를 출력하시오.
select min(sal) 최소급여 , max(sal) 최대급여
from emp;

     최소급여          최대급여

     800       5000

문제) 부서번호와 급여평균을 출력하시오.
select deptno, avg(sal)
from emp;
---> 에러발생 ORA-00937: not a single-group group function
---> select절에서는 단순컬럼과 함께 그룹함수 사용금지!!


- DQL형식)

  1. select 조회컬럼명

  2. from   테이블명

  3. where  (전체행에 대한)조건식

  4. group by (그룹을 묶을 수 있는 조건을 가진)컬럼명

  5. having  (그룹에 대한)조건식

  6. order by 정렬컬럼명;

     ★실행순서!!  :  2- 3- 4- 5- 1(조회)- 6  - 출력  

select deptno, avg(sal)
from emp
group by deptno; -- 부서별로 그룹을 묶겠음!! -- 그룹함수와 컬럼이 매핑할 근거 마련

  DEPTNO   AVG(SAL)

      30 1566.66667
      20       2175
      10 2916.66667

  ==> 부서별 평균 급여           

 문제1) 사원들의 직급종류는 몇 개 (= 몇 행)인지 출력하시오.
 select job
 from emp
 group by job;


  문제2) 전체사원의 수(=전체 행의 갯수)를 구하시오.
  select ename
  from emp
  group by ename;

  문제3) 가장 오래 근무한 사원의 입사일을 구하시오.
  select min(hiredate) "입사일"
  from emp;

  문제4) 부서별 평균 급여를 구하시오.(부서번호가 작은 부서부터 출력)
  select floor(avg(sal)) "부서별 평균급여"
  from emp
  group by deptno;


  문제5) 부서의 평균 급여가 2000 이상인 부서의 부서번호와 평균 급여를 출력하시오.
  select deptno, avg(sal) "부서별 평균급여"
  from emp
  group by deptno
  having avg(sal)>=2000;

  문제6) 평균급여(==> 2073.21429)보다 더 많은 급여를 받은 사원의 사원번호, 사원명, 급여를 출력하시오.
  select empno, ename, sal 
  from emp
  where sal > avg(sal);


  문제7) 급여가 1000 이상인 사원들에 대해서만 부서별로 평균을 구하고
        이 중에 평균 급여가 2000 이상인 부서의 부서번호와 평균급여를 출력하시오.

문제1) 사원들의 직급종류는 몇 개(=몇 행)인지 출력하시오.
select count(job)
from emp;
==> 14

   왜 14?

SQL> select job from emp;

JOB

CLERK
SALESMAN
SALESMAN
MANAGER
SALESMAN
MANAGER
MANAGER
ANALYST
PRESIDENT
SALESMAN
CLERK
CLERK
ANALYST
CLERK
---> 14명 사원들의 각각 직책 수!!

select distinct job
from emp;

JOB

CLERK
SALESMAN
PRESIDENT
MANAGER
ANALYST
---> 중복제거된 14명 사원들의 직책!!

select count(distinct job)
from emp;
==> 5

문제2) 전체사원의 수(=전체 행의 갯수)를 구하시오.
select count(empno)
from emp;
==> 14

select count(ename)
from  emp;
==> 14

select count(hiredate)
from  emp;
==> 14

select count(comm)
from  emp;
==> 4

select count(mgr)
from  emp;
==> 13

select count(*)
from emp;
==> 14!!

문제3) 가장 오래 근무한 사원의 입사일을 구하시오.
select min(hiredate)
from emp;

select to_char(min(hiredate),  'yyyy/mm/dd'  ) "오래된 입사일"
       , to_char(max(hiredate),  'yyyy/mm/dd'  ) "가장 최근 입사일"
from   emp;

오래된 입사일 가장 최근 입사일


1980/12/17 1987/05/23

문제4) 부서별 평균 급여를 구하시오.(부서번호가 작은 부서부터 출력)
select deptno, avg(sal)
from emp
group by deptno
order by deptno;

  DEPTNO   AVG(SAL)

      10 2916.66667
      20       2175
      30 1566.66667   

문제5) 부서의 평균 급여가 2000 이상인 부서의 부서번호와 평균 급여를 출력하시오.

       ==> 부서별 그룹에 대한 조건!!

 select deptno, avg(sal)
 from   emp
 group by deptno
 having  avg(sal) >= 2000;

  DEPTNO   AVG(SAL)

      20       2175
      10 2916.66667

문제6) 평균급여(==> 2073.21429)보다 더 많은 급여를 받은 사원의 사원번호, 사원명, 급여를 출력하시오.

           전체(14명 사원)에 대한 조건!!

select empno, ename, sal
from   emp
where  sal > avg(sal);

에러발생: ORA-00934: group function is not allowed here
===> where절에서는 그룹함수 사용이 불가!!

 where 조건식
       ------
             컬럼명      연산자    데이터          
             데이터      연산자    컬럼명          
             데이터      연산자    데이터          
             컬럼명      연산자    컬럼명          

select empno, ename, sal
from   emp
where  sal > 2073.21429;

select empno, ename, sal
from   emp
where  sal > (select avg(sal) from emp);

문제7) 급여가 1000 이상인 사원들에 대해서만 부서별로 평균을 구하고
이 중에 평균 급여가 2000 이상인 부서의 부서번호와 평균급여를 출력하시오.
select deptno, avg(sal)
from emp
where sal >= 1000
group by deptno
having avg(sal) >= 2000;



  • NVL, NVL2, NULLIF, COALESCE의 차이점
    *NVL은 NULL값을 지정된 값으로 바꾼다.(모든 데이터 타입 적용 가능)
    *NVL2(expr, expr1, expr2는 NULL이 아니면 expr1의 값 반환, NULL이면 expr2 값 반환
    *NULLIF(exp1, exp2) 는 exp1과 exp2의 값이 동일하면 NULL 그렇지 않으면 exp1
    *coalesce(expr1, expr2, expr3.....)은 순서대로 조회하며 NULL이 아닌값 반환 expr1이 NULL이 아니면 expr1 그렇지 않으면 coalesce(exp3,expr3....)값 반환
    *여기서 NVL은 oracle함수이고, COALESCE는 ANSI 표준 함수

  • TRUNC와 FLOOR의 차이

    • -마이너스에서만 차이가 있다.

    • SQL> select Trunc(-45.245) from dual;

      TRUNC(-45.245)

                -45

      SQL> select Floor(-45.245) from dual;

      FLOOR(-45.245)

                -46

      위처럼 마이너스에서 TRUNC는 그냥 잘라내기만 하고, FLOOR는 내림처리가 된다.
      SQL> select Trunc(-10/3) from dual;

      TRUNC(-10/3)

               -3

      SQL> select Floor(-10/3) from dual;

      FLOOR(-10/3)

               -4

      *이렇게 -10을 3으로 나누는 연산등에서 값이 바뀌는 결과가 발생 할 수 있다.


190523_Day31 DB2


DB랑 DBMS 를 명확하게 구별 할 것

  • DB(DataBase) 는 체계화 된 데이터의 모임
  • 여러사람 공유목적, 데이터의 집합
  • 서버라고 생각하면 안됨, 저장소라고 생각해야 함!
  • DBMS(DataBase Management System)
  • 데이터베이스 관리 시스템
  • 효과적 이용 위해 정리, 보관 소프트웨어
  • 데이터 추가,조회,수정,삭제 등 기능을 집대성한 소프트웨어 패키지
  • 데이터베이스를 구축하는 틀을 제공
  • 효율적으로 데이터를 검색하고 저장하는 기능
  • 응용 프로그램들이 데이터베이스에 접근할 수 있는 인터페이스 제공
  • 장애에 대한 복구, 보안 유지 기능 제공

SQL*PLUS 명령어 : 접속 툴 내에서 출력형식을 지정하는 등 환경설정. (아주 중요한 것은 아니다)

<SQL.>

  • 관계형 데이터베이스의 ANSI 표준언어
  • 여러줄 실행
  • 종결문자필요(;)
  • 키워드 단축 불가
  • 버퍼에 마지막 명령문 저장
  • 대소문자 구분 없음 (TABLE명, COLUMN명을 SeLecT 이렇게 써도 됨. 단, 데이터를 표시할 때는 반드시 대소문자 구분! 'Gildong', 'gildong')

<SQL*PLUS>

  • 오라클 DB접속툴
  • 한줄실행
  • 종결문자 불필요
  • 키워드 단축 가능
  • 버퍼저장 안함

SQL*PLUS 명령어

  • L[IST] : 가장 마지막에 실행한 SQL문 출력

  • ED[IT] : 지정된 파일을 메모장을 통해 열어줌.

  • SAVE 파일명 : 명시된 파일명으로 버퍼에 있는 SQL문을 저장

    save hello.sql;
    //맨 처음 들어온 경로 sqlplus 접근한 곳
  • GET 파일명: 명시된 파일 SQL문 얻어오기

  • SPOOL(갈무리)

    #시작
    SPOOL 파일명
    SQL문1;
    SQL문2;
    SQL문3;
    #끝
    SPOOL OFF  
    
    ===> SQL문1 부터  SQL문3 까지 지정된 파일명으로 저장
    • HOST: SQL접속을 유지한 상태에서 커맨드 상태로 이동 (sql프롬프트 ----> windows프롬프트)
    • EXIT: 커맨드상태에서 SQL프롬프트상태로 이동 (windows프롬프트 ----> sql프롬프트)
  • LINE, PAGESIZE(한 페이지에 출력되는 라인사이즈): 출력형식

      형식) SET 명령어 값
  • 행과 열이 짤린다면

    1. SQL>set linesize 300;
      1. SQL>set pagesize 100;
        위와 같이 출력 사이즈를 수정하자
    SQL> set pages17
    SQL> select empno, ename, sal from emp;
    
         EMPNO ENAME                       SAL
    ---------- -------------------- ----------
          7369 SMITH                       800
          7499 ALLEN                      1600
          7521 WARD                       1250
          7566 JONES                      2975
          7654 MARTIN                     1250
          7698 BLAKE                      2850
          7782 CLARK                      2450
          7788 SCOTT                      3000
          7839 KING                       5000
          7844 TURNER                     1500
          7876 ADAMS                      1100
          7900 JAMES                       950
          7902 FORD                       3000
          7934 MILLER                     1300
  • 명령어 설명 참조)명령어 뭔지 모르겠으면 ? set 혹은 help set으로 도움말 보기 가능

    /          : 버퍼에 저장된 마지막 sql문  실행
    R[UN]      : 버퍼에 저장된 마지막 sql문  출력과 실행
    @test.sql  : 파일내의 sql문  실행
ed test.sql

show user

select tname from tab; // 모든테이블 보여준다

<WHERE절> - 조건절, 출력행을 제어하는 역할

형식)

SELECT 컬럼명 //전체 열중 원하는 열만 선택 : 열을 제어

FROM 테이블명

WHERE 조건식(conditions); // 전체 행중 원하는 행만 선택 : 행을 제어

FROM - WHERE SELECT 순서로 읽는다.

※ 조건식 구성

기준컬럼명 연산자 비교데이터
(비교연산자)
> , < , >= , <=
= (같다, 등가연산자)
!=(다르다), ^=, <>

문제) 전체 사원의 사원번호, 사원명, 부서번호를 출력.
select empno, ename, deptno
from emp;

   EMPNO ENAME                    DEPTNO
  7369 SMITH                        20
  7499 ALLEN                        30
  7521 WARD                         30
  7566 JONES                        20
  7654 MARTIN                       30
  7698 BLAKE                        30
  7782 CLARK                        10
  7788 SCOTT                        20
  ....
  ===> 14행의 출력

문제) 30번 부서에 근무하는 사원의 사원번호, 사원명, 부서번호를 출력.
select empno, ename, deptno
from emp
where deptno = 30;

문제) 30번 부서에 근무하지않은 사원의 사원번호, 사원명, 부서번호를 출력.

select empno, ename, deptno
from emp
where deptno != 30; //혹은 (deptno=10 OR deptno=20)

문제) SMITH사원의 사원번호, 사원명, 입사일, 부서번호를 출력하시오.

​ SELECT empno, ename, hiredate, deptno

​ from emp

​ where upper(ename) = upper('sMiTh');

문제1 ) 20번 부서에 근무하는 사원의 사원번호, 사원명, 직책, 급여를 출력하시오

select empno, ename,job, sal
from emp
where deptno = 20;

문제2 ) 직책이 manager인 사원의 사원번호, 사원명, 직책, 입사일을 출력하시오

SELECT empno, ename,job, hiredate
FROM emp
WHERE  job = 'MANAGER';

문제3) 급여가 2000 이상인 사원의 사원번호, 사원명, 급여를 출력하시오.

SELECT empno, ename, sal
FROM emp
WHERE sal >= 2000;

문제4) FORD사원의 사원번호, 사원명, 부서번호를 출력하시오.

SELECT empno, ename, deptno
FROM emp
WHERE ename = 'FORD';

문제5) 1981년 6월 1일 이후에 입사한 사원의 사원번호, 사원명, 부서번호, 입사일을 출력하시오.

SQL> SELECT empno, ename, deptno, hiredate
  2  FROM emp
  3  WHERE hiredate >= '810601';

       EMPNO ENAME                    DEPTNO HIREDATE
---------- -------------------- ---------- --------
      7654 MARTIN                       30 81/09/28
      7782 CLARK                        10 81/06/09
      7788 SCOTT                        20 87/04/19
      7839 KING                         10 81/11/17
      7844 TURNER                       30 81/09/08
      7876 ADAMS                        20 87/05/23
      7900 JAMES                        30 81/12/03
      7902 FORD                         20 81/12/03
      7934 MILLER                       10 82/01/23

문제6) 10번 부서에 근무하는 사원의 사원번호, 사원명, 매니저의 사원번호를 출력하시오.

select empno, ename, mgr
from emp
where deptno = 10;

문제7) 20번과 30번 부서에 근무하는 사원의 사원번호, 사원명, 매니저의 사원번호를 출력하시오.

select empno, ename, mgr
from emp
where deptno = 20 OR deptno = 30;

     EMPNO ENAME                       MGR
---------- -------------------- ----------
      7369 SMITH                      7902
      7499 ALLEN                      7698
      7521 WARD                       7698
      7566 JONES                      7839
      7654 MARTIN                     7698
      7698 BLAKE                      7839
      7788 SCOTT                      7566
      7844 TURNER                     7698
      7876 ADAMS                      7788
      7900 JAMES                      7698
      7902 FORD                       7566

문제8) 10,20번 부서의 부서번호, 부서명, 부서위치를 조회하시오.

select deptno, dname, loc
from dept
where deptno = 10 OR deptno = 20;

문제9) 3등급 급여의 최소급여와 최대급여를 출력하시오.

SELECT losal, hisal
from salgrade
where grade = 3;

===> 급여 3등급은 1401이상 ~ 2000이하 !!

where 조건식1 OR|AND 조건식2
where 조건식1 OR 조건식2 AND 조건식3

  2

          1
    ------------  

A || B && C 순차적 실제

0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 1 1 1 1
1 0 0 0 1 ==> check
1 0 1 1 1
1 1 0 0 1 ==> check

1 1 1 1 1

System.out.println( 1<2 || 1<3 && 300>500); //true
---- --- -------
조건식1 조건식2 조건식3

select dname
from dept
where 조건식3 AND 조건식2 OR 조건식1

select dname
from dept
where 300>500 AND 1<3 OR 1<2;
==> 4행 출력 System.out.println( 1<2 || 1<3 && 300>500); //true

select dname
from dept
where 300>500 AND (1<3 OR 1<2);
==> 0행 출력 System.out.println( (1<2 || 1<3) && 300>500); //false

====================================================================
<조건식의 구성>
컬럼명 연산자 비교데이터

<LIKE연산자>
형식) 컬럼명 LIKE 'pattern'
----> 패턴과 닮은 컬럼이 속한 행을 조회
----> 패턴내의 예약문자(횟수를 표현하는 문자)
% : 0~n개의 문자를 대체
_ : 단 1개의 문자를 대체

DB에 저장된 문자데이터 예) 'a', 'ab', 'ad', 'abc', 'abbbbb', 'bababa'

like 'a' -----> 'a' : % 또는 _ 문자를 사용하지 않는다면 등호와 같은 결과!! = 'a'

like 'a%' -----> a문자로 시작하는 데이터!! -----> 'a', 'ab', 'ad', 'abc', 'abbbbb'

like 'a__' -----> 'abc'

like '%a' -----> a문자로 끝나는 데이터!! -----> 'a', 'bababa'

like '__c' -----> 'abc'

like '%a%' -----> a문자를 포함하는 데이터!! -----> 'a', 'ab', 'ad', 'abc', 'abbbbb', 'bababa'

문제) 사원명이 'A'로 시작되는 사원의 정보(사원번호,사원명,급여)를 출력하시오
select empno, ename, sal
from emp
where ename like 'A%';

     EMPNO ENAME                       SAL
---------- -------------------- ----------
      7499 ALLEN                      1600
      7876 ADAMS                      1100

문제) 사원명이 'S'로 끝나는 사원의 정보(사원번호,사원명,급여)를 출력하시오
select empno, ename, sal
from emp
where ename like '%S';

 EMPNO ENAME                       SAL

  7566 JONES                      2975
  7876 ADAMS                      1100
  7900 JAMES                       950   

문제) 사원명에 'A'문자가 포함된 사원의 정보(사원번호,사원명,급여)를 출력하시오
select empno, ename, sal
from emp
where ename like '%A%';

  EMPNO ENAME                       SAL
  7499 ALLEN                      1600
  7521 WARD                       1250
  7654 MARTIN                     1250
  7698 BLAKE                      2850
  7782 CLARK                      2450
  7876 ADAMS                      1100
  7900 JAMES                       950               

문제) 사원명의 세번째 문자에 'A'문자가 포함된 사원의 정보(사원번호,사원명,급여)를 출력하시오
select empno, ename, sal
from emp
where ename like 'A';

문제) 사원명에 '%'문자가 포함된 사원의 정보(사원번호,사원명,급여)를 출력하시오
==> 테스트를 위해 잠시 '%'포함된 사원정보 입력!! ==> insert into emp (empno, ename, sal)
values (8000, '홍%길동' , 2500);

SELECT empno, ename, sal
from emp
where ename like '%%%';

※참고)

ESCAPE옵션 : '%' 또는 '_'를 와일드 카드가 아닌 문자의 의미를 가지고자 할 때 사용

​ -> 컬럼명 LIKE '패턴' ESCAPE '부호';

​ 이스케이프 구분자!!

select empno, ename, sal
from emp
where ename like '%%%' escape '';

rollback; -----------> 작업취소(insert 이전의 상태로 되돌리기!!)

<IN 연산자>

콤마로 구분하는 배열데이터

형식) 컬럼명 IN (value_list)

​ => 컬럼의 값이 value_list에 데이터와 하나라도 일치한다면!!

​ (OR연산자 유사)

문제) 커미션을 300 , 500, 1400 받는 사원들의 정보 ( 사원번호, 사원명, 부서번호, 커미션)를 출력하시오

select empno, ename, deptno, comm
from emp
where comm = 300 or comm = 500 or comm = 1400;
select empno, ename, deptno, comm
from emp
where comm in (300, 500, 1400);

<BETWEEN AND 연산자> : 범위 조건시 사용

형식) 컬럼명 BETWEEN a AND b => a:최소값, b:최대값 => a이상 b이하

​ 컬럼명 BETWEEN 최소값 AND 최대값

​ BETWEEN 1 and 100 => 1이상 100이하

주의) BETWEEN AND 연산자는 초과와 미만을 표현을 못함!!

문제) 급여가 1600 이상이고 3000 이하인 사원의 정보(사원번호, 사원명, 급여)를 출력하시오.

SELECT empno, ename, sal
from emp
where 1600 <= sal <= 3000;
    => 에러 : 한 컬럼을 두개 이상의 값과 동시에 비교할 수 없음
SELECT empno, ename, sal
from emp
where sal >= 1600
    AND
    sal <= 3000;
SELECT empno, ename, sal
from emp
where sal between 1600 AND 3000;        //거꾸로 하면 3000 AND 1600 하면 조회 불가

문제) 커미션을 받는 사원의 사원번호, 사원명, 부서번호, 커미션을 출력하시오

SELECT empno, ename, deptno, comm
from emp
where comm > 0;
SELECT empno, ename, deptno, comm
from emp
where comm is not null;

문제) 커미션을 받지 않는(커미션이 null인, 커미션을 받지 않은 조건 ) 사원의 사원번호, 사원명, 부서번호, 커미션을 출력하시오

SELECT empno, ename, deptno, comm
from emp
where comm is null;

☆★데이터 값이 null인 것을 체크(비교) : 컬럼명 IS NULL

​ null이 아닌것은

​ null이 아닌것을 체크

<NULL데이터> ★

  • 미확정 데이터 (같은 행에서 입력되지 않은 데이터)

  • 연산, 할당, 비교가 불가능!! (결과행에서 배제)

    comm=null

    3000+null ==> null

   select empno, ename, deptno, comm
   from   emp
   where  comm is null;

null 연산, 비교, 할당 불가 -> 가능은 하지만 결과도 null

문제) 커미션을 받을 조건이 되는 사원의 사원번호, 사원명, 부서번호, 커미션을 출력하시오

   select empno, ename, deptno, comm
   from   emp
   where  comm is not null;

문제) 전체사원의 사원번호, 사원명, 급여, 연봉(comm포함)을 출력하시오.

select empno, ename, sal, sal*12+comm "연봉"
   from emp;                              

     EMPNO ENAME                       SAL       연봉
---------- -------------------- ---------- ----------
      7369 SMITH                       800
      7499 ALLEN                      1600      19500
      7521 WARD                       1250      15500
      7566 JONES                      2975
      7654 MARTIN                     1250      16400
      7698 BLAKE                      2850
      7782 CLARK                      2450
      7788 SCOTT                      3000
      7839 KING                       5000
      7844 TURNER                     1500      18000
      7876 ADAMS                      1100                                 
 select empno, ename, sal, sal*12+  NVL(comm,0) "연봉"
   from emp;  

     EMPNO ENAME                       SAL       연봉
---------- -------------------- ---------- ----------
      7369 SMITH                       800       9600
      7499 ALLEN                      1600      19500
      7521 WARD                       1250      15500
      7566 JONES                      2975      35700
      7654 MARTIN                     1250      16400

<NVL함수>

  • null변환 함수
    형식)
    NVL( null값이 예상되는 컬럼명 , 대체할 데이터 )
    ===> ※주의: 첫번째인자와 두번째인자는 서로 자료형이 같아야 함!!

문제) 사원들의 사원번호, 사원명, 커미션을 출력하되
커미션을 받지않는(커미션의 값이 null) 사원들은 0으로 출력하시오.

  select empno, ename, comm
  from emp;

     EMPNO ENAME                      COMM
---------- -------------------- ----------
      7369 SMITH
      7499 ALLEN                       300
      7521 WARD                        500
      7566 JONES
      7654 MARTIN                     1400
      7698 BLAKE
      7782 CLARK
  select empno, ename, nvl(comm, 0) comm 
  from emp;

     EMPNO ENAME                       COMM
---------- -------------------- -----------
      7369 SMITH                          0
      7499 ALLEN                        300
      7521 WARD                         500
      7566 JONES                          0
      7654 MARTIN                      1400
      7698 BLAKE                          0
      7782 CLARK                          0
      7788 SCOTT                          0

문제) 사원들의 사원번호, 사우너명, 커미션을 출력하되 커미션을 받지않는 (커미션의 값이 null) 사원들은 '없음'으로 출력하시오

    select empno, ename, nvl(comm,'없음') comm 
  from emp;                    //에러발생 인자가 서로 다른 자료형

  select empno, ename, nvl(TO_CHAR(comm),'없음') comm 
  from emp;                                                    

  EMPNO ENAME                COMM
---------- -------------------- --------------------------------------------------------------------------------
      7369 SMITH                없음
      7499 ALLEN                300
      7521 WARD                 500
      7566 JONES                없음
      7654 MARTIN               1400
      7698 BLAKE                없음
      7782 CLARK                없음
      7788 SCOTT                없음
      7839 KING                 없음
      7844 TURNER               0
      7876 ADAMS                없음
      7900 JAMES                없음
      7902 FORD                 없음
      7934 MILLER               없음   
           to_number                 to_date              
      <------------------    ----------------------->
 NUMBER                  CHAR                        DATE
      ------------------>    <-----------------------
           to_char                   to_char

문제) 10번 부서에 근무하는 사원들의 사원번호, 사원명, 직책, 매니저(상사)를 출력하시오.
(단, 매니저가 없는 경우 'CEO'를 출력하시오.)

select empno, ename, job, nvl(to_char(mgr),'CEO') mgr
from emp
where deptno = 10;

<ORDER BY절>

  • 정렬하여 출력

형식)

SELECT 컬럼명
FROM 테이블명
WHERE 조건식
ORDER BY (정렬하고자 하는)컬럼명 [ASC|DESC];

---> ASC (ascending) : 오름차순 정렬(기본값!!) abcde 012345 가나다라
---> DESC(descending) : 내림차순 정렬 edcba 543210 라다나가

문제) 30번 부서에 근무하는 사원의 사원번호, 사원명, 급여를 출력하되
사원번호에 대해 내림차순으로 정렬하시오.

SELECT empno, ename, sal
FROM emp
WHERE deptno = 30
ORDER BY EMPNO DESC;

문제) 30번 부서에 근무하는 사원의 사원번호, 사원명, 급여를 출력하되
사원명에 대해 오름차순으로 정렬하시오.

SELECT empno, ename, sal
FROM emp
WHERE deptno = 30
ORDER BY EMPNO ASC;

문제) 30번 부서에 근무하는 사원의 사원번호, 사원명, 급여를 출력하되
급여를 많이 받는 순으로 출력하시오.

SELECT empno, ename, sal
FROM emp
WHERE deptno = 30
ORDER BY sal DESC;

문제) 가장 최근에 입사한 사원부터 사원번호, 사원명, 급여, 입사일을 출력하시오.

SELECT empno, ename, sal, hiredate
FROM emp
ORDER BY hiredate DESC;

문제) 급여가 많은 순으로 사원번호, 사원명, 급여를 출력하시오.
(단, 급여가 같을 경우 사원명을 기준으로 오름차순 출력하시오.)

ORDER BY 1차정렬 컬럼명 [오름/내림] , 2차정렬 컬럼명 [오름/내림]

SELECT empno, ename, sal
FROM emp
ORDER BY sal DESC, ename ASC;

삼일째

 

240p 짜리 요약집 중 1과목 정독

(대강대강 읽으면서 큰 틀만 머리속에 정리함)

 

 

아침 안함... 아침에 지하철에서 낑겨서 뭐 하기가 너무 싫다... 그래도 내일은 꼭... 하자 꼭

수업후 150분 요약집 공부

집가면서 30분 강의 볼(예정)

 

총 180분

'SQLD' 카테고리의 다른 글

190530 SQLD 공부-6  (0) 2019.05.30
190529 SQLD 공부-5  (0) 2019.05.29
190527 SQL 공부-4  (0) 2019.05.27
190522 SQL 공부-2  (0) 2019.05.22
190521 SQL 공부  (0) 2019.05.21

이틀째

 

20p짜리 요약집 계속 읽고, 240p 짜리 요약집 인쇄

 

아침 안함...

수업후 140분 요약집 공부

집가면서 30분 강의 볼(예정)

 

총 170분

'SQLD' 카테고리의 다른 글

190530 SQLD 공부-6  (0) 2019.05.30
190529 SQLD 공부-5  (0) 2019.05.29
190527 SQL 공부-4  (0) 2019.05.27
190523 SQL 공부-3  (0) 2019.05.23
190521 SQL 공부  (0) 2019.05.21

190522_Day30 DB(Oracle)

오라클 설치

데이터베이스 개요

  • 데이터베이스란?

    • 관리해야 하는 데이터를 모아놓은 집합체
    • 데이터의 중복없이 서로 연관되어 있는 집합
    • 행과 열의 형태
  • DBMS란, 프로그램과 DB사이의 매개체, 징검다리 (서버)

    • DataBaseManagementServer
    • 서버 사용 용도 뿐만 아닌 내부 저장용도로도 사용됨
  • 데이터베이스의 목적

    • 중복 최소화
    • 공유
    • 보안유지
    • 무결성
  • 파일관리시스템

    • 검색,추가,수정,삭제 기능을 사용자가 원하는 정보를 이요할 수 있게 해주는 프로그램
  • 단점

    • 데이터의 중복성
    • 데이터의 불일치
    • 프로그램 데이터간의 종속성
    • 제한적인 정보 제공
      • 독립적인 파일을 갖고 그 각각에 파일에 대한 정보만 제공
    • 보안문제
  • 관계 데이터 모형

    • 일직선상의 데이터 나열이 아닌
    • 행(row) 열(Column)을 사용하여 표시
  • 데이터베이스 구조

    • 물리적(내부)
    • 논리적(개념적)
    • 사용자(외부)
      • 위의 세개의 사이에는 물리적 독립성과 논리적 독립성이 보장되어야 하며 이는 자료 독립성을 보장하게 한다.

<DB관련 수업>

Java - SQL(Structured Query Language) - JDBC - ibatis(MyBatis)

데이터 저장하는 인메모리, 파일, DB중 DB를 하고 있는 것.

<DB접속>

  • 접속 툴 : 토드, SQL Developer(오라클 제공), 이클립스, SQL*PLUS

  • SQL*PLUS 는 수업할 때나 사용, 이를 통해 접속한다.

  • 1558490278630

  • cmd에서 sqlplus 계정명/패스워드 로도 가능

  • <오라클 계정>

    • SYS : 오라클 Super 사용자 계정이며 데이터베이스에서 발생하는 모든 문제들을 처리 할 수 있는 권한을 가짐
      • sqlplus /nolog
      • conn /as sysdbs
    • SYSTEM : 오라클 데이터베이스를 유지보수 및 관리할 때 사용하는 계정
      • 명령프롬프트창 : sqlplus system/oracle
      • SQL명령창 : conn system/oracle
    • SCOTT, HR : 처음 오라클을 사용하는 사용자를 위해 만들어 놓은 사용자 계정

    <데이터베이스 관리자 접속을 해서 사용자 [SCOTT]을 만들고 권한 주기>

    • 관리자 접속

    • C:\Users\Playdata // 윈도우즈 관련 명령어 입력 대기상태!
      C:\Users\Playdata>sqlplus
      Enter user-name: system
      Enter password:oracle
      SQL>_
    • 사용자 계정 만들기

    • CREATE USER [user_name]
      IDENTIFIED BY [password];
      
      SQL> create user scott
        2  identified by tiger;
      
      User created.    
    • SQL은 명령어에서 대소문자 구별 안함!

    • 생성된 scott계정의 접속 시도

      • 방법1) 현재 연결된 [system]관리 계정에서 접속을 끊고 다시 [scott]유저 접속하기

      • exit
        sqlplus scott/tiger
      • 방법2) 계정 접속만 변경하기

      • conn scott/tiger
      • 엥 그런데 에러 발생?!

      • ERROR:
        ORA-01045: user SCOTT lacks CREATE SESSION privilege; logon denied
      • 뭐야... 이게?

        • 접속 권한 불충분!
    • 생성된 계정(User)에게 연결 권한 부여(관리자가)

      • grant connect,resource to scott;
        Grant succeeded.
        
        SQL> conn scott/tiger
        Connected.
        SQL> show user
        USER is "SCOTT"
        SQL>
        
    • <접속 계정에서의 생성된 테이블 종류 보기(검색)>

      • select * from tab;
        ---> no rows selected(검색된 테이블 정보 없음)
    • <예제 테이블 정보 가져오기(복사하기)>

      • imp scott/tiger file=c:\Yongjin\scottTable.dmp fromuser=scott touser=scott constraints=y commit=y ignore=y tables=dept,empsalgrade
    • 주의) SQL>_프롬프트상태에서는 SQL관련 명령어만 입력 => imp는 sql명령어가 아님

      • C:\Users\Playdata>_프롬프트상태의 imp입력!
      • 반드시 한줄로 입력
      • file뒤에 dmp파일이 실제 존재하는 곳을 명시!
      • 확인) select tname from tab;
    • TNAME

      DEPT
      EMP
      SALGRADE

    • <각 테이블의 구조(컬럼명, 자료형) 검색>

    • DESC[RIBE] 테이블명 - 테이블을 구성하는 컬럼(속성)과 자료형을 표현

    • describe emp

    •  Name                                      Null?    Type
       ----------------------------------------- -------- ----------------------------
       EMPNO (사원번호)                           NOT NULL      NOT NULL NUMBER(4)
       ENAME (사원명)                                           VARCHAR2(10)
       JOB (직책)                                               VARCHAR2(9)
       MGR (매니저,직속상사)                                     NUMBER(4)
       HIREDATE (입사일,고용일)                                  DATE
       SAL (급여)                                               NUMBER(7,2)
       COMM (커미션,특별수당,성과급여)                            NUMBER(7,2)
       DEPTNO (사원이 속한 부서번호)                             NUMBER(2)
    • SQL> desc dept - (부서테이블 - 3개의 속성으로 구성)

    •  Name                                      Null?    Type
       ----------------------------------------- -------- ----------------------------
       DEPTNO (부서번호)                                   NOT NULL NUMBER(2)
       DNAME  (부서명)                                     VARCHAR2(14)
       LOC    (부서위치)                                   VARCHAR2(13)
    • SQL> desc salgrade - (급여등급테이블 - 3개의 속성으로 구성)

    •  Name                                      Null?    Type
       ----------------------------------------- -------- ----------------------------
       GRADE                                              NUMBER
       LOSAL                                              NUMBER
       HISAL                                              NUMBER
      

Structured Query Language ( 구조적인 질의어 )

  • 종류 ) 암기사항
    1. ★데이터 정의어(DDL) : Data Definition Language
      • 데이터베이스 관리자나 응용프로그래머가 데이터베이스의 논리적인 구조를 정의하기 위한 언어
      • 객체( 예 : Table, View( 가상테이블 ), Sequence, Trigger )에 대한 정의
      • 명령어 : CREATE(생성), DROP(삭제), ALTER, RENAME, TRUNCATE(포크레인 처럼 데이터를 제거해주는)
    2. ★데이터 조작어(DML) : Data Manipulation Language
      • 데이터베이스에 저장된 데이터를 조작(추가, 수정, 삭제) 하기 위해 사용하는 언어
      • 명령어 : INSERT, UPDATE, DELETE
    3. 데이터 제어어(DCL) : Data Control Language
      • 데이터베이스에 대한 접근 권한 부여등의 데이터베이스 시스템의 관리를 위한 목적으로 사용되는 언어
      • 명령어 : GRANT( 권한 부여 ), REVOKE( 권한 회수 ),
    4. ★데이터 질의어(DQL) : Data Query Language
      • 검색, 조회 명령어
      • 명령어 : SELECT
    5. 트랜잭션 제어어(TCL) : Transaction Control Language
      • 논리적인 작업단위의 묶음
      • 다수개의 DML에 대한 묶음.
      • ATM에 비유함, 했던 행동들을 취소할 수 있는, 혹은 확정지을 수 있는 명령
      • 명령어 : COMMIT, ROLLBACK, SAVEPOINT( ROLLBACK과 연관, 저장점 )

<테이블에 저장된 데이터에 대한 검색(조회)>

SELECT명령문 사용

  • 형식)

  • SELECT (조회하고자 하는)컬럼명
    FROM (컬럼이 속한)테이블명;
    ---
    SELECT 컬럼명1, 컬럼명2
    FROM 테이블명;
    ---
    부서테이블 조회(모든 속성)
    SELECT deptno, dname, loc
    FROM dept;
    
  • SQL> select deptno, dname, loc
      2  from dept;
    
        DEPTNO DNAME                        LOC
    ---------- ---------------------------- --------------------------
            10 ACCOUNTING                   NEW YORK
            20 RESEARCH                     DALLAS
            30 SALES                        CHICAGO
            40 OPERATIONS                   BOSTON
  • 부서테이블 조회(부서명, 부서위치)

  • select DNAME, loc;
    => ORA-00923: FROM keyword not found where expected 에
    ---
    select DNAME, loc
    from dept;
    
    DNAME                        LOC
    ---------------------------- --------------------------
    ACCOUNTING                   NEW YORK
    RESEARCH                     DALLAS
    SALES                        CHICAGO
    OPERATIONS                   BOSTON
    
  • <테이블내의 데이터를 검색>

  • 형식)

  • SELECT 컬럼명1, 컬럼명2 (또는 출력할 데이터)
    FROM (컬럼 속한) 테이블명
  • 문제

  • 문제1) 급여등급, 최소급여, 최대급여 조회
    SQL> select grade, losal, hisal
      2  from salgrade
      3  ;
    
         GRADE      LOSAL      HISAL
    ---------- ---------- ----------
             1        700       1200
             2       1201       1400
             3       1401       2000
             4       2001       3000
             5       3001       9999
    
    문제2) 부서명과 부서위치 출력
    SQL> select dname,loc
      2  from dept;
    
    DNAME                        LOC
    ---------------------------- --------------------------
    ACCOUNTING                   NEW YORK
    RESEARCH                     DALLAS
    SALES                        CHICAGO
    OPERATIONS                   BOSTON
    
    문제3) 사원번호, 사원명,입사일,급여를 조회
    SQL> select empno,ename,hiredate, sal
      2  from EMP;
    
         EMPNO ENAME                HIREDATE        SAL
    ---------- -------------------- -------- ----------
          7369 SMITH                80/12/17        800
          7499 ALLEN                81/02/20       1600
          7521 WARD                 81/02/22       1250
          7566 JONES                81/04/02       2975
          7654 MARTIN               81/09/28       1250
          7698 BLAKE                81/05/01       2850
          7782 CLARK                81/06/09       2450
          7788 SCOTT                87/04/19       3000
          7839 KING                 81/11/17       5000
          7844 TURNER               81/09/08       1500
          7876 ADAMS                87/05/23       1100
    
         EMPNO ENAME                HIREDATE        SAL
    ---------- -------------------- -------- ----------
          7900 JAMES                81/12/03        950
          7902 FORD                 81/12/03       3000
          7934 MILLER               82/01/23       1300
    
    문제4) "안녕, SQL~!"을 화면에 출력
        =>  SELECT : 컬럼조회와 출력에 사용하는 SQL명령어.
        SQL> select '안녕, SQL~!' as hi // 만약 h 띄고 i 로 하고 싶다면 "" 큰따움표로 묶어주기
      2  from emp;
    
        ※오라클에서는 테이블에 상관없는 데이터를 출력하기 위해 시스템 테이블을 지원!
        =>dual테이블(dumy테이블, 가상테이블)
        => <별칭 사용하기>
        SELECT 컬럼명 [AS] 별명
        FROM 테이블명;
        //AS는 생략가능
        주의)오라클은 문자, 문자열 데이터 표현 시 ''작은 따옴표 사용!, ""큰따옴표는 컬럼명 또는 별명 표현하는 용도로 사용
    
    문제5) 화면에 사원번호와 사원명 출력
    SQL> select empno "사원번호" ,ename "사원명"
      2  from emp;
    
      사원번호 사원명
    ---------- --------------------
          7369 SMITH
          7499 ALLEN
          7521 WARD
          7566 JONES
          7654 MARTIN
          7698 BLAKE
          7782 CLARK
          7788 SCOTT
          7839 KING
          7844 TURNER
          7876 ADAMS
    
      사원번호 사원명
    ---------- --------------------
          7900 JAMES
          7902 FORD
          7934 MILLER
    
    문제6) 각 사원들의 사원번호 사원명 급여 연봉
       select empno, ename, sal salary, sal*12 "연 봉"
       from  emp; 
         EMPNO ENAME                    SALARY      연 봉
    ---------- -------------------- ---------- ----------
          7369 SMITH                       800       9600
          7499 ALLEN                      1600      19200
          7521 WARD                       1250      15000
          7566 JONES                      2975      35700
          7654 MARTIN                     1250      15000
          7698 BLAKE                      2850      34200
          7782 CLARK                      2450      29400
          7788 SCOTT                      3000      36000
          7839 KING                       5000      60000
          7844 TURNER                     1500      18000
          7876 ADAMS                      1100      13200
    
         EMPNO ENAME                    SALARY      연 봉
    ---------- -------------------- ---------- ----------
          7900 JAMES                       950      11400
          7902 FORD                       3000      36000
          7934 MILLER                     1300      15600
    
    문제7) 사원들의 이름과 직책을 출력하시오.
    (출력 변경 => SMITH사원의 직책은 CLERK입니다.)
    SQL> select ename || '사원의 직책은' || job || '입니다.' "사원 직책"
      2  from emp;
    
    사원 직책
    --------------------------------------------------------------------------------
    SMITH사원의 직책은CLERK입니다.
    ALLEN사원의 직책은SALESMAN입니다.
    WARD사원의 직책은SALESMAN입니다.
    JONES사원의 직책은MANAGER입니다.
    MARTIN사원의 직책은SALESMAN입니다.
    BLAKE사원의 직책은MANAGER입니다.
    CLARK사원의 직책은MANAGER입니다.
    SCOTT사원의 직책은ANALYST입니다.
    KING사원의 직책은PRESIDENT입니다.
    TURNER사원의 직책은SALESMAN입니다.
    ADAMS사원의 직책은CLERK입니다.
    
    사원 직책
    --------------------------------------------------------------------------------
    JAMES사원의 직책은CLERK입니다.
    FORD사원의 직책은ANALYST입니다.
    MILLER사원의 직책은CLERK입니다.
    
    문제8) 사원들의 직책을 출력하되, 중복된 내용은 제거
    select distinct job  
    from emp;
    JOB
    ------------------
    CLERK
    SALESMAN
    PRESIDENT
    MANAGER
    ANALYST
    
    문제9) 10과 3의 사칙연산의 결과를 출력하는 SQL문을 작성하시오.
    SQL> select 10+3 더하기, 10-3 빼기, 10*3 "곱하기", 10/3 나누기
      2  from dual;                                       0/3 나누기
    
        더하기       빼기     곱하기     나누기
    ---------- ---------- ---------- ----------
            13          7         30 3.33333333
    
    SQL> select 10+3 "더하기", 10-3 빼기, 10*3 "곱하기", floor(10/3) floor나누기, mod(10,3) mod나누기
      2  from dual;
    
        더하기       빼기     곱하기 FLOOR나누기  MOD나누기
    ---------- ---------- ---------- ----------- ----------
            13          7         30           3          1
    
    SQL>
  • <별칭 alias 사용하기>

  • 형식)

  • SELECT 컬럼명 [AS] 별명
    FROM 테이블명;
    //AS는 생략가능
  • <Concatenation 연산자> //Concat이라고도 부름

    • 접합연산자 : ||
    • '문자열1' || '문자열2' =>> '문자열1문자열2'
    • select ename || '사원의 직책은' || job || '입니다.' "사원 직책"
    • from emp;
  • <DISTINCT 키워드> : 중복제거 기능

  • 형식)

  • SELECT DISTINCT (중복이 예상되는) 컬럼명
    FROM 테이블명;

첫 공부 시작

 

20p짜리 요약집으로 시작

 

아침 30분 지하철 강의 공부

수업후 80분 요약집 공부

집가면서 60분 강의 공부(예정)

 

총 170분

'SQLD' 카테고리의 다른 글

190530 SQLD 공부-6  (0) 2019.05.30
190529 SQLD 공부-5  (0) 2019.05.29
190527 SQL 공부-4  (0) 2019.05.27
190523 SQL 공부-3  (0) 2019.05.23
190522 SQL 공부-2  (0) 2019.05.22

+ Recent posts