1. SYSDATE
  - 시스템이 제공하는 날짜 및 시각정보(년,월,일,시,분,초) 반환
  -  '+', '-' 연산이 가능하며, 날짜자료 사이의 뺄셈의 결과는 두 날짜사이의 날수(Days)를 반환

  --정오를 기준으로 반올림될수도 있음


  2. ADD_MONTHS(d, n)
 - 날짜자료 d에 포함된 월에 n을 더한 날짜 반환
 
사용예)-- 더해줄 개월 수// 출력은 날짜정보

    SELECT EMPLOYEE_ID,
           EMP_NAME,
           HIRE_DATE,
           ADD_MONTHS(HIRE_DATE,3) 
      FROM HR.EMPLOYEES;

 

 

 

 

 

 

3. NEXT_DAY(d, c) -- 주어진 날짜의 다음 만나는 요일
  - 날짜 자료 d 이후에 처음 만나는 c 요일의 날짜 반환
  - c는 '월요일', '월',....'일요일','일' 중 하나 기술
  
  
사용예)
    SELECT NEXT_DAY(SYSDATE, '금') FROM DUAL;
    SELECT NEXT_DAY(SYSDATE, '토요일') FROM DUAL;

 

4. LAST_DAY(d) - *** --년월일 있어야 함
  - 날짜자료 d 에 포함된 월의 마지막 일자를 반환
  - 주로 2월의 마지막 일자나 확정되니 않은 월의 마지막일자가 필요한 경우 사용

사용예) 회원테이블에서 각 회원의 생년월일에 포함된

월의  마지막 일을 조회하시오

  SELECT MEM_ID,
         MEM_NAME,
         MEM_BIR,
         LAST_DAY(MEM_BIR)
    FROM MEMBER;

 

 

4. LAST_DAY(d) - *** --년월일 있어야 함
  - 날짜자료 d 에 포함된 월의 마지막 일자를 반환
  - 주로 2월의 마지막 일자나 확정되니 않은 월의 마지막일자가 필요한 경우 사용

사용예) 키보드로 년도와 월을 입력받아 해당 월에 발생된 매입수량과 매입금액합게를 출력하시오

ACCEPT P_PERIOD PROMPT '년도와 월(YYYYMM) 입력 ; ' -- ACCEPT 메세지 기술
  DECLARE
         L_SDATE DATE := TO_DATE('&P_PERIOD'||'01');  -- 시작일자
         L_EDATE DATE := LAST_DAY(L_SDATE);       -- 월의 종료 일자
         L_SQTY NUMBER:=0; --수량합계 // 숫자변수 초기화 시켜야함 // 안하면 무한루트
         L_SUM NUMBER:=0; -- 매입금액합계
    BEGIN
        SELECT SUM(A.BUY_QTY), SUM(A.BUY_QTY*B.PROD_COST) INTO L_SQTY,L_SUM
        --셀렉트 INTO절 변수에 하나씩 넣는다
          FROM BUYPROD A, PROD B
    WHERE A.BUY_PROD=B.PROD_ID
      AND A.BUY_DATE BETWEEN L_SDATE AND L_EDATE;       
          DBMS_OUTPUT.PUT_LINE('기간 : '||L_SDATE||'~'||L_EDATE);
          DBMS_OUTPUT.PUT_LINE('매입수량 합계 : '||TO_CHAR(L_SQTY,'9,999')||'개');
          DBMS_OUTPUT.PUT_LINE('매입금액 합계 : '||TO_CHAR(L_SUM,'999,999,999')||'원');
          DBMS_OUTPUT.PUT_LINE('----------------------------------');   
  END; 

---------------------------------------
기간 : 2020/06/01~2020/06/30
매입수량 합계 :    206개
매입금액 합계 :   48,090,000원

 

5. EXTRACT(fmt FROM d) - *****  -- 추출하다
  - 주어진 날짜 자료 d 에서 'fmt'로 정의된 값을 반환
  - 'fmt'는 YEAR, MONTH, DAY, MINUTE, SECOND 중 하나
  - 결과는 숫자형 자료임
  
사용예) 회원테이블에서 회원들의 생년월일(MEM_BIR) 컬럼의 값을 사용하여 나이를 계산하시오
    Alias 회원번호,회원명,생년월일,나이

    SELECT MEM_ID AS 회원번호,
           MEM_NAME AS 회원명,
           MEM_BIR AS 생년월일,
           EXTRACT(YEAR FROM SYSDATE) - EXTRACT(YEAR FROM MEM_BIR) AS 나이 
           -- 오늘날짜 정보에서 '년도'를 뽑음 - 맴버 생년월일의 년도를 뽑음
     FROM MEMBER



 

 

 

사용예) 회원테이블에서 이번달 생일인 회원을 찾아 보너스 마일리지를 100포인트씩 지급하려 한다.
       이번달 생일인 회원정보를 조회하시오
       Alias 회원번호,회원명,생년월일,원마일리지,변경마일리지
   

SELECT MEM_ID AS 회원번호,
       MEM_NAME AS 회원명,
       MEM_BIR AS 생년월일,
       MEM_MILEAGE AS 원마일리지,
       MEM_MILEAGE + 100 AS 변경마일리지
  FROM MEMBER
 WHERE EXTRACT(MONTH FROM SYSDATE)=EXTRACT(MONTH FROM MEM_BIR)

 

 

6. MONTHS_BETWEEN(d1,d2) -**
  - 두 날짜자료 d1과 d2 사이의 개월 수를 반환
  - 경력계산 등 날짜 자료 중 개월 수가 필요한 경우 사용
  
사용예) 사원테이블에서 80번 부서의 직원들의 근속년수를 계산하시오.
       근속년수는 월단위 까지 계산하시오(XXS년 XX월)
       Alias는 사원번호,사원명,입사일,직무코드,근속년수

 

 SELECT EMPLOYEE_ID AS 사원번호,
        EMP_NAME AS 사원명,
        HIRE_DATE AS 입사일,
        JOB_ID AS 직무코드,
        ROUND(MONTHS_BETWEEN(SYSDATE,HIRE_DATE)) AS 근속개월수,
        TRUNC(MONTHS_BETWEEN(SYSDATE,HIRE_DATE)/12)||'년'|| 
        -- XXX월을 12로 나누면 몫: 년수
        LPAD(ROUND(MOD(MONTHS_BETWEEN(SYSDATE,HIRE_DATE),12)),3)||'개월'
        AS 근속년수-- XXX월을 12로 나눈 나머지 : 개월수
   FROM HR.EMPLOYEES
  WHERE DEPARTMENT_ID = 80;

 

 

 

1. 수학적 함수
  - ABS,SIGN,SQRT,EXP,LOG,POWER....
  1) ABS(n), SIGN(n), SQRT(n), POWER(n,e)
    - ABS : n의 절대값 -- 부호를 없앤 값
    - SIGN : n의 부호 값(n이 양수이면 1, 음수이면 -1, 0이면 0 반환) -- 크기는 따지지 않고 부호만 확인함
    - SQRT : n의 평방근 --루트 값
    - POWER : n의 e승(n^e) 값을 반환 --거듭제곱값

사용예)

    SELECT ABS(-1000),ABS(0),ABS(0.0001),
           SIGN(-0.0009), SIGN(0),SIGN(100000), -- 참, 거짓 확인 가능
           SQRT(1024), -- 루트 값 =32 * 32
           POWER(2,10) -- 2의 10승
      FROM DUAL;


 

 2) GREATEST(n1,n2[,....], LEAST(n1,n2[,.....]) 
  - GREATEST : 주어진 수 n1 ~ n 에서 가장 큰 수를 반환
               MAX와 차이점은 MAX는 하나의 컬럼 값 중 가장 큰 것을 반환 -- MAX는 한 열에서 제일 큰 값
               GREATEST는 여러 컬럼중 가장 큰 값을 반환 --GREATEST는 한 행에서 제일 큰 값
  - LEAST : 주어진 수 n1 ~ n 에서 가장 작은 수를 반환
            MIN와 차이점은 MIN는 하나의 컬럼 값 중 가장 작은 것을 반환
            LEAST는 여러 컬럼중 가장 작은 값을 반환

SELECT GREATEST(PROD_COST,PROD_PRICE,PROD_SALE)   

-- 3개의 컬럼 중에 각 상품별 제일 큰 값       
        FROM PROD;

 SELECT MAX(PROD_COST) 
-- 매입가격중에 제일 큰 매입가격 : 1개만
   FROM PROD;  

MAX 값 : 3150000

 

 

 

 

문제] 회원테이블에서 회원들의 보유 마일리지가 1000보다 작은 회원들의 마일리지를 1000으로 변경시켜 출력하시오
        Alias는 회원번호,회원명,원본 마일리지

   SELECT MEM_ID AS 회원번호,
          MEM_NAME AS 회원명,
          MEM_MILEAGE AS 원본마일리지,
          GREATEST(MEM_MILEAGE,1000) AS 변경마일리지
-- GREATEST : 원본 마일리지와 1000을 비교해서
-- 더 큰값을 반환한다.
     FROM MEMBER;

 


--      숫자, 위치값 / loc는 자리 위치
 3) ROUND(n,[,loc]), TRUNC(n,[,loc])
  - ROUND는 반올림을 수행하고 TRUNC는 자리버림을 수행함
  - 숫자 n에서 loc +1번째 자리에서 반올림(자리버림) 하여 loc 자리까지 결과 반환
  - loc가 음수이면 정수부분 loc자리에서 반올림(자리버림) 후 값 반환
  - loc가 생략되면 0으로 간주됨

 

    SELECT ROUND(123.45678,2),  -- 123.46 : 소숫점 아래 3번째에서 반올림
           ROUND(123.45678),    -- 123 : loc 생략 = 0
           ROUND(123.45678,-2), -- 100 : 정수 2번째 자리에서 반올림 : 100
           TRUNC(123.45678,2),  -- 123.45 : 소숫점 아래 3번째에서 숫자를 자름
           TRUNC(123.45678),    -- 123 :  loc 생략 = 0
           TRUNC(123.45678,-2)  -- 100 : 정수 2번째 자리에서 버림
      FROM DUAL;

 

 

사용예) 상품테이블의 상품별 마일리지컬럼(PROD_MILEAGE)에 판매단가의 0.6% 해당하는 값을 입력하시오.
       단 모든 값은 정수로 입력하시오. 업데이트 /모든 상품으로 WHERE 절 없음

    UPDATE PROD
       SET PROD_MILEAGE=ROUND(PROD_PRICE*0.006);
       
    COMMIT;

 

 

사용예) 상품테이블에서 각 상품들의 원가율(매입가격/판매가격)을 %로 출력하시오.
        단, 원가율을 소숫점 1자리까지 구하며, 원가율이 큰 상품부터 출력하시오.
        Alias는 상품코드, 상품명, 매입가격, 판매가격,원가율
        원가율 = 매입가격/판매가격 -> 소수 첫째자리까지

 SELECT PROD_ID AS 상품코드, 
        PROD_NAME AS 상품명, 
        PROD_COST AS 매입가격, 
        PROD_PRICE AS 판매가격,
        ROUND(PROD_COST/PROD_PRICE,3)*100||'%'
        AS 원가율 
   FROM PROD
  ORDER BY 5 DESC;

 


 

 4) FLOOR(n), CEIL(n) -**
  - FLOOR : n과 같거나 작은수 중 제일 큰 정수(n을 초과하지 않는 최대 정수)
                   세금과 같이 징수 계산에 주로 사용
  - CEIL : n과 같거나 큰 수중 제일 작은 정수 (n을 보다 작지 않은 최소 정수)
              주로 급여와 값이 지급액 계산에 주로 사용
  - 주로 급여, 세금 등과 같은 금액 관련 계산에 주로 사용
  
사용예)

    SELECT FLOOR(20), FLOOR(20.999),FLOOR(-20.67),
            -- 20       /   20     /    -21
           CEIL(20), CEIL(20.999),CEIL(-20.67) 
  -- 20 /   21 : 20.999보다 큰 수중 가장 작은수 / -20 :  음수 -20.67 보다 큰 수는 -20이다
     FROM DUAL;

 

 5) MOD(n1, n2), REMAINDER(n1, n2) -***
  - 나머지를 반환
  - MOD는 일반적인 나머지를 반환하며, REMAINDER는 나머지가 젲수의 절반보다 큰 값이면 
    현재수에서 다음 몫의 수를 차감한 결과를 반환
  - 내부적으로 MOD와 REMAINDER는 사용하는 함수가 다름
 
  - MOD = n1 - n2 * FLOOR(n1/n2)
  - REMAINDER = n1 - n2 * ROUND(n1/n2)
  

 

MOD(29,5) = 29 - 5 * FLOOR(29/5) -- 첫번째 매개변수를 두번째 매개변수로 나눔 (분자/분모) 나머지를 반환한다.
          = 29 - 5 * FLOOR(5.8) -- 반환되는 값은 FLOOR 사용
          = 29 - 5 * 5
          = 4          -- 29 / 5 의 몫은 5 / 5.8 => 라운드로 반올림하면 6 // 29 -30 = -1
REMAINDER(29,5) =  = 29 - 5 * ROUND(29/5) -- 몫과 나머지를 반환하는데 실행되는 함수가 다르다.
                   = 29 - 5 * ROUND(5.8) -- 반올림 사용
                   = 29 - 5 * 6
                   = -1
    SELECT MOD(27,5), MOD(29,5),
           REMAINDER(27,5),REMAINDER(29,5)
      FROM DUAL;

 


 6) WIDTH_BUCKET(n, min, max, b) - ** -- 하한값 : min / 상한값  : max
  - 구간의 하한값 min 에서 상한값 max까지 b개의 블록으로 구분하고 주어진 값 val이
    속한 구간의 index값을 반환
  - val 값은 각 구간의 상한값과 같은 경우 다음 구간 순번을 반환. 

    즉, 구간 하한<= val < 구간 상한 -- min<= 값 < max
  - b는 전체구간을 분할할 갯수를 의미하며 사용되는 구간의 갯수는 b + 2 개이다.

   (총구간의 개수는 b+2 // min 보다 하한의 값은 0구간 , b구간, max 보다 상한의 값은 b+1구간 )
  
사용예) 회원테이블에서 회원들의 마일리지를 기준으로 1000-8000까지를 3개의 구간으로 구분하고 
        회원들이 어느 구간에 속하는지를 판별하시오
        Alias는 회원번호,회원명,마일리지,구간값

SELECT MEM_ID AS 회원번호, 
       MEM_NAME AS 회원명,
       MEM_MILEAGE AS 마일리지, 
       WIDTH_BUCKET(MEM_MILEAGE,1000,8000,3) AS 구간값 
-- min 보다 하한의 값은 0구간
  FROM MEMBER 
-- max 보다 상한의 값은 b+1구간

                                                                                                             

 

 -- 마일리지 구간을 반대로 8000이상을 1 구간으로 정렬

   SELECT MEM_ID AS 회원번호, 
          MEM_NAME AS 회원명, 
          MEM_MILEAGE AS 마일리지, 
          5-WIDTH_BUCKET(MEM_MILEAGE,1000,8000,3) AS 구간값
     FROM MEMBER    
  
 
   SELECT MEM_ID AS 회원번호, 
          MEM_NAME AS 회원명, 
          MEM_MILEAGE AS 마일리지, 
          1 + WIDTH_BUCKET(MEM_MILEAGE,8000,999,3) AS 구간값 
     FROM MEMBER

 

 *** CASE WHEN THEN 표현식
    - 자바의 SWITCH ~ CASE 와 비슷한 기능 제공
    - SELECT 절에서만 사용가능 (PL/SQL에서는 명령문으로 제공)

(사용형식_1)
    CASE WHEN 조건식1 THEN   -- CASE WHEN = if(조건식)
              명령1
         WHEN 조건식2 THEN
              명령2
              .
              .
        ELSE -- = 자바 스위치 문의 default
              명령n
    END
      . 조건식1을 평가하여 그 값이 참이면 '명령1'을 수행하고 거짓이면 다음 WHEN을 수행
      . 조건식이 모두 만족하지 않은 경우 마지막 ELSE 다음의 '명령n'을 수행
       

 

 CASE WHEN 값1 THEN
              명령1
        WHEN 값2 THEN
              명령2
              .
              .
        ELSE
              명령n
    END
      . 조건식을 평가하여 그 값이 '값1' 이면 명령1을 '값2'면 명령2를 수행하고
        맞는 값이 없으면 '명령n'을 수행

 

사용예) 회원테이블에서 회원들의 마일리지를 기준으로 1000-8000까지를 3개의 구간으로 구분하고 
        회원들이 어느 구간에 속하는지를 판별하고 그 값이
        0-1이면 '열심회원'
        2-3이면 '보통회원'
        4 이상이면 '새싹회원'을 비고에 출력하시오
         Alias는 회원번호,회원명,마일리지,구간값,비고

 SELECT MEM_ID AS 회원번호, 
        MEM_NAME AS 회원명, 
        MEM_MILEAGE AS 마일리지, 
        WIDTH_BUCKET(MEM_MILEAGE,8000,1000,3) AS 구간값,
   CASE WHEN  WIDTH_BUCKET(MEM_MILEAGE,8000,1000,3) IN(0,1) 
        THEN
            '열심회원'
        WHEN WIDTH_BUCKET(MEM_MILEAGE,8000,1000,3) IN(2,3) 
        THEN
            '보통회원'
        ELSE
            '새싹회원'
         END AS 비고        
   FROM MEMBER;

 

 

오라클 함수


 - 함수는 미리 프로그램으로 구성되어 실행파일 형태로 제공되는 모듈
 - 컬럼 값이나 데이터 타입의 변환
 - 숫자 날짜 자료의 출력 형식 변화
 - 단일행 함수와 복수행 함수
 - 문자열, 날짜, 숫자, null처리, 형변환, 집계함수, window 분석함수 등으로 구분
 

함수의 종류 크게 2가지 있음

- 오라클 제공 / 보통 사용하는 함수 = 단일행 함수

- 사용자 프로그램 생성 : 사용자 정의 함수

 

복수행 함수 집계 함수 : 합계(sum), 평균(avg), max, min, count(갯수)

복수행 연산자(IN, ANY, SOME, ALL, EXISTS)를 써야한다.

 → 반드시 group by 절이 나와야 한다.

함수는 함수안에 함수를 가질수 있다. BUT, 집계함수는 집계함수를 포함할 수 없다.

 

1. 문자열 함수
  1) '||'(문자열 결합 연산자)
   - 주어진 2개의 문자열을 결합하여 새로운 문자열을 반환
   - 자바의 문자열 연산자 '+'와 동일 기능 제공
   
  2) CONCAT(c1,c2) /--캐릭터// 바인딩 변수 = 매개변수(Parameter, argument) : 

                                    바인딩 (변수가 기억공간을 할당 받고 값이 매겨지는 것)
   - 'c1'과 'c2'로 주어진 문자열을 결합하여 결과 반환 -- d : DATE / n : number
   
사용예) 사원테이블에서 사원들의 FIRST_NAME과 LAST_NAME을 결합하여 출력하시오

    SELECT CONCAT(FIRST_NAME,LAST_NAME)
      FROM HR.EMPLOYEES

 

 

 

 


사용예) 회원테이블에서 거주지가 '충남'인 회원들을 조회하시오
        Alias는 회원번호,회원명,주민번호,직업,마일리지이며, 주민번호는 'XXXXXX-XXXXXXX'
        형식으로 출력하며 CONCAT 함수를 사용할 것
   

SELECT MEM_ID AS 회원번호,
       MEM_NAME AS 회원명,
       MEM_REGNO1||'-'||MEM_REGNO2 AS 주민번호1,
       CONCAT(CONCAT(MEM_REGNO1,'-'),MEM_REGNO2) AS 주민번호2, 

-- 자료의 타입은 문자열 타입 + 
       CONCAT(MEM_REGNO1,CONCAT('-',MEM_REGNO2)) AS 주민번호3,
       MEM_JOB AS 직업,
       MEM_MILEAGE AS 마일리지 
  FROM MEMBER 
 WHERE MEM_ADD1 LIKE '충남%' ;

 




 3) LOWER(C), UPPER(C), INITCAP(C) -- ** (사용빈도수)
  - LOWER : 주어진 문자열에 포함된 대문자 자료를 소문자로 변환      
  - UPPER : 주어진 문자열에 포함된 소문자 자료를 대문자로 변환
  - INITCAP : 단어의 시작 문자만 대문자로 변환(이름 들을 표현할 경우 사용)

     -- 이니셜 캐피탈 : 첫글자만 대문자로 바꾸기
  - 문자열이 포함된 컬럼을 이용한 조건 처리시 문자가 대문자인지 소문자인지 구별할 수 없는 경우 주로 사용됨
  
사용예) 회원테이블에서 회원번호 'T001'회원정보를 조회하시오
        Alias는 회원번호,회원명,주소,전화번호이다
     

  SELECT MEM_ID AS 회원번호,
         MEM_NAME AS 회원명,
         MEM_ADD1||' '||MEM_ADD2 AS 주소,
         MEM_HP AS 전화번호
    FROM MEMBER 
   WHERE UPPER(MEM_ID)='T001'; -- 't001'소문자로 출력


        
사용예)

SELECT A.EMP_NAME AS 사원명1,
       LOWER(A.FIRST_NAME||' '||A.LAST_NAME) AS 사원명2, -- 전부 소문자 문자열로 바뀜
       INITCAP(LOWER(A.FIRST_NAME||' '||A.LAST_NAME)) AS 사원명3, 

-- 단어의 첫글자만 대문자로 변경 //미들네임도 바뀜
        B.DEPARTMENT_ID AS 부서명,
        A.JOB_ID AS 직무코드,
        A.HIRE_DATE AS 입사일
  FROM HR.EMPLOYEES A, HR.DEPARTMENTS B
 WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID 

--A테이블의 부서코드 = B테이블의 부서코드가 맞으면
 ORDER BY A.DEPARTMENT_ID;


 -- 107명인데 결과는 106명 => 부서이름은 부서테이블에서 가져옴
 -- 사원테이블의 어떤 사원은 부서가 NULL값이고 해서 조건에 안맞으면 버림. 

A. 테이블의 부서코드 =NULL / B.테이블은 있음 => 출력안됨.

 

 


 

4) LPAD(c1, n [,c2]),RPAD(c1,n [,c2]) -- 레프트, 라이트 
   - LPAD : 문자열 'c1'을 n바이트 크기의 기억장소에 오른쪽부터 출력하고 남는 왼쪽 공간에             

                  문자열 'c2'를 모두 채움. 'c2'가 생략되면 공백을 채움  

-- 공간을 왼쪽에 남겨놔야 하니까 오른쪽부터 저장
   - RPAD : 문자열 'c1'을 n바이트 크기의 기억장소에 왼쪽부터 출력하고 남는 오른쪽 공간에 

                  문자열 'c2'를 모두 채움. 'c2'가 생략되면 공백을 채움

-- 공간을 오른쪽에 남겨놔야 하니까 왼쪽부터 저장
   - 수표보호 문자나 크기를 정하여 자료를 오른쪽 또는 왼쪽 정렬하여 출력할 때 주로 사용

 

※ pad : padding 특정한 문자를 특정한 공간에 채우는 것

 


사용예) 상품테이블에서 분류코드 'P202'에 속한 상품들의 상품코드,상품명,매입단가,매출단가를 조회하시오.
       단, 매입단가 및 매출단가의 출력은 3자리마다 자리점(',')을 넣어 출력하시오
     

SELECT PROD_ID AS 상품코드,
       PROD_NAME AS 상품명,
       LPAD(TO_CHAR(PROD_COST),10,'*') AS 매입단가,

 --           글자 공간에 오른쪽부터 적고 남는공간은 *로 채우세요
 --    LPAD(TO_CHAR(PROD_PRICE,'9,999,999'),10,' ') AS 매출단가
       LPAD(TRIM(TO_CHAR(PROD_PRICE,'9,999,999')),10,'*') AS 매출단가, --TRIM 남는공간
       LPAD(TRIM(TO_CHAR(PROD_SALE,'9,999,999')),10) AS 할인판매단가,
       TO_CHAR(PROD_SALE,'9,999,999')
  FROM PROD
 WHERE UPPER(PROD_LGU)='P202'

-- '9,999,999' 세자리 점 출력
-- TRIM : 양쪽에 발생된 모든 공백을 자름 => 남는 기억장소 '*'로 채움

 



 5)LTRIM(c1,[,c2]),RTRIM(c1,[,c2]) -- ***
   - LTRIM : 문자열 'c1'의 왼쪽부터 'c2'를 찾아 일치하는 문자열을 제거함

                   ('c1'의 왼쪽 시작글자가 'c2'와 일치해야한다.
                    , 'c2'가 생략되면 왼쪽 공백을 제거함
   - RTRIM : 문자열 'c1'의 오른쪽부터 'c2'를 찾아 일치하는 문자열을 제거함

                   ('c1'의 오른쪽 시작글자가 'c2'와 일치해야한다.
            , 'c2'가 생략되면 오른쪽공백을 제거함
   - 문자열 내부의 공백은 제거할 수 없음
        
-- 시작되는 첫 글짜가 같아야함 C1 = C2        

사용예) 

    SELECT 'COCONUT',
            LTRIM(' COCONUT','CO'), --앞에 공백이 있어서 안맞아서 제거 못함
            LTRIM('COCONUT','CO'), -- 공백 없이, 'COCO' 둘다 없앰 : NUT
            LTRIM(' COCONUT') -- 왼쪽에 공백,, 단어 내부의 공백은 지울수 없음
      FROM DUAL

**회원테이블에서 회원명 컬럼의 데이터 타입을 CHAR(20)으로 변경하시오
   ALTER TABLE MEMBER MODIFY(MEM_NAME CHAR(20));
  
사용예) 회원테이블에서 '신용환' 회원의 회원번호,직업,마일리지를 조회하시오

   SELECT MEM_ID AS 회원번호,
          MEM_JOB AS 직업,
          LENGTH(RTRIM(MEM_NAME)) AS 이름1, --글자수 3
          LENGTH(MEM_NAME) AS 이름2, -- 글자수 14 '공백포함'
          MEM_MILEAGE AS 마일리지
     FROM MEMBER
--  WHERE MEM_NAME='신용환'; --공백이 없다. 
-- 오라클에서 양쪽에 발생된 공백을 TRIM으로 잘라서 비교하기때문에 에러가 안난다.
    WHERE TRIM(MEM_NAME)='신용환';

    
6) TRIM(c) - ***
  - 문자열 'c'의 앞과 뒤의 모든 공백을 제거함
  - 문자열 내부 공백 제거는 불가능
  
사용예) 회원테이블의 회원명 컬럼은 VARCHAR2(20)으로 변경하시오.

    ALTER TABLE MEMBER MODIFY(MEM_NAME VARCHAR2(20));
    COMMIT;
    
    SELECT MEM_ID,MEM_NAME
      FROM MEMBER;

 -- 아직 공백이 존재함/단어 내부의 공백은 유효한 공백으로 제거할 수 없다.


    UPDATE MEMBER 
       SET MEM_NAME=TRIM(MEM_NAME); 
        
     SELECT MEM_ID,MEM_NAME
       FROM MEMBER;

        
        
7) SUBSTR(c, m[,n] -- *****
  - 제시된 문자열 중 일부분을 추출하여 결과로 반환
  - 문자열 'c'에서 m번째 문자부터 n글자를 추출하여 반환
  - n이 생략되거나 글자의 수보다 큰 값의 n이 사용되면 m번째 이후 모든 글자를 반환
  - m은 1번 부터 사용
  - m이 음수이면 오른쪽 m번째 부터 n 글자를 추출하여 반환 함
    
  
사용예) 2020년 6월 구매고객을 모두 조회하시오.
        Alias는 고객번호,고객명,직업,마일리지

SELECT DISTINCT A.CART_MEMBER AS 고객번호,
                B.MEM_NAME AS 고객명,
                B.MEM_JOB AS 직업,
                B.MEM_MILEAGE AS 마일리지
  FROM CART A, MEMBER B
 -- WHERE CART_NO LIKE '202006%'
 WHERE SUBSTR(A.CART_NO,1,6) = '202006'
   AND A.CART_MEMBER=B.MEM_ID

  

 


사용예) 2020년 6월 모든 매입 상품정보를 조회하시오
        Alias는 상품코드,상품명,매입단가,매입처코드

  SELECT A.BUY_PROD AS 상품코드,
         B.PROD_NAME AS 상품명,
         B.PROD_COST AS 매입단가,
         B.PROD_BUYER AS 매입처코드
    FROM BUYPROD A, PROD B
   WHERE A.BUY_PROD=B.PROD_ID
     AND A.BUY_DATE BETWEEN TO_DATE('20200601') 
     AND TO_DATE('20200630');
-- 날짜 자료에는 BETWEEN 연산자를 쓰자



 

사용예) 2020년 5월 구매고객 중 첫 구매 고객정보를 조회하시오  -- 구매 관련은 cart 
       Alias는 회원번호,회원명,주소

SELECT DISTINCT A.CART_MEMBER AS 회원번호,
       TO_DATE(SUBSTR(A.CART_NO,1,8)) AS 날짜,
       B.MEM_NAME AS 회원명,
       B.MEM_ADD1||' '||B.MEM_ADD2 AS 주소
  FROM CART A, MEMBER B
 WHERE A.CART_MEMBER=B.MEM_ID
   AND SUBSTR(A.CART_NO,1,6)='202005'
   AND SUBSTR(A.CART_NO,9)='00001'
 ORDER BY 2;

 

CART_NO에서 2020050100001 => 에서 날짜를 떼고 '00001' 인 고객 조회 => 해당날짜의 첫 고객

 


 8) REPLACE(c1, c2[,c3]) -- ***
   - 문자열 c1에 포함된 c2문자열을 찾아 c3문자열로 대치시킴
   - c3가 생략되면 찾은 c2를 제거함 --공백을 치면 공백을 찾아서 제거함
   
사용예) 상품테이블의 상품명에 '대우'를 찾아 '애플'로 변경하시오.

    SELECT PROD_NAME,
           REPLACE(PROD_NAME,'대우','애플'),
           REPLACE(PROD_NAME,' ')  -- 데이터 내부에 있는 공백을 제거함
      FROM PROD;

                                                                       ↓  대우 => 애플                                ↓공백 제거                     

 


 

 9) INSTR(c1, c2[,m [,n]) -** --index of string 문자열의 위치값
   - 문자열 c1에서 c2가 처음 나온 위치값(index)을 반환
   - m은 시작위치를 지정--m은 찾는 위치
   - n은 c2가 반복하여 사용되었을 경우 찾고자 하는 횟수 (반복횟수) 지정
   
 10) LENGTH(c), LENGTHB(c) - *
   - LENGTH : 문자열 c에 포함된 문자의 수 반환
   - LENGTHB : 문자열의 c의 길이를 byte 수로 반환

 

 

Oracle SQL - SQL(Structure Query language)

- 구조적 질의 처리기
 . 변수, 분기문, 반복문 등이 존재하지 않음
- 1973년 SQUARE로부터 출발
- 1986년 ANSI-86표준안(1988년 ISO인정)
- 1992, 1999년 표준안 개정
- 명령의 분류
 . 검색명령 : SELECT
 . DML(Data Manipulation Language) : INSERT / UPDATE / DELETE
 . DLL(Data Definition Language) : CREATE / ALTER / DROP 등
 . DLC(Data Control Language) : GRANT / REVOKE / COMMIT / ROLLBACK / SAVEPOINT 등
 
 1. CREATE TABLE 명령
  - 테이블 생성 명령
  (사용형식)
  CREATE TABLE 테이블명 (
    컬럼명 데이터타입[(크기)] [NOT NULL][DEFAULT 값] [,]
                        .
                        .
    컬럼명 데이터타입[(크기)] [NOT NULL][DEFAULT 값] [,]
    [CONSTRAINT 기본키설정명 PRIMARY KEY(컬럼명[,컬럼명,....])[,]]
    [CONSTRAINT 왜래키설정명 FOREIGN KEY(컬럼명)
        REFERENCES 테이블명(컬럼명)] [,]
                        .
                        .
    [CONSTRAINT 왜래키설정명 FOREIGN KEY(컬럼명)
        REFERENCES 테이블명(컬럼명)];


 . '데이터타입' : 오라클에서 사용할 수 있는 자료타입 기술
   - 문자열타입 : CHAR, VARCHAR, VARCHAR2, CLOB, LONG 등
   - 숫자타입 : NUMBER
   - 날짜타입 : DATE, TIMESTAMP
   - 이진자료 : RAW, BLOB, BFILE 등
 . 'DEFAULT 값' : 사용자가 기술하지 않았을 경우 기본적으로 입력되는 값
 . '기본키설정명' : 기본키 설정에 붙여지는 이름으로 고유한 이름이여야 함
 . 'PRIMARY KEY(컬럼명,..)' : 기본키로 사용되는 컬럼명
 . '왜래키설정명' : 왜래키 설정에 붙여지는 이름으로 고유한 이름이여야 함
 . 'REFERENCES 테이블명(컬럼명)' : 부모테이블명과 부모테이블에서 사용된 컬럼명
 
 사용예) 한국건설 테이블 설계에 따른 테이블을 생성하시오.
 1. 사원 테이블(EMP)

 CREATE TABLE EMP(
    EMP_ID CHAR(4),
    EMP_NAME VARCHAR2(30) NOT NULL,
    DEPT_NAME VARCHAR2(50),
    TEL_NUM VARCHAR2(20), --왜래키 없음, 기본키만 있음
    CONSTRAINT pk_EMP_ID PRIMARY KEY(EMP_ID));


 
 -- emp_id 소문자로 써도 됨. 나중에 저장 대문자로 출력
 -- rerode 해야 테이블 생김
 2. 사업장 테이블(SITE)

CREATE TABLE SITE(
    SITE_ID NUMBER(5),
    SITE_NAME VARCHAR2(50) NOT NULL,
    SITE_ADDR VARCHAR2(500),
    SITE_TELNUM VARCHAR2(20),
    CONSTRAINT pk_SITE PRIMARY KEY(SITE_ID));



 3. 사업장 자재테이블(SITE_MAT)

 CREATE TABLE SITE_MAT(
    SMAT_ID VARCHAR2(5) NOT NULL,
    SMAT_NAME VARCHAR2(50) NOT NULL,
    SMAT_QTY NUMBER(5) DEFAULT 0,
    SITE_ID NUMBER(5),
    CONSTRAINT pk_SMAT_ID PRIMARY KEY(SMAT_ID),
    CONSTRAINT fk_SMAT_SITE FOREIGN KEY(SITE_ID) REFERENCES SITE(SITE_ID));
--  CONSTRAINT 왜래키설정명   FOREIGN KEY(컬럼명)  REFERENCES 테이블명(컬럼명)


4. 근무테이블(WORK_TBL)

  CREATE TABLE WORK_TBL(
    SITE_ID NUMBER(5),
    EMP_ID CHAR(4),
    SDATE DATE,
    EDATE DATE,
    CONSTRAINT PK_WORK PRIMARY KEY(EMP_ID,SITE_ID),
    CONSTRAINT FK_WORK_EMP FOREIGN KEY(EMP_ID) REFERENCES EMP(EMP_ID),
    CONSTRAINT FK_WORK_SITE FOREIGN KEY(SITE_ID) REFERENCES SITE(SITE_ID));
    근무테이블(WORK_TBL)


    
 

CREATE TABLE WORK_TBL2(
    SITE_ID NUMBER(5),
    EMP_ID CHAR(4),
    SDATE DATE,
    EDATE DATE,
    CONSTRAINT PK_WORK2 PRIMARY KEY(EMP_ID,SITE_ID),
    CONSTRAINT FK_WORK2_EMP FOREIGN KEY(EMP_ID) REFERENCES EMP(EMP_ID),
    CONSTRAINT FK_WORK2_SITE FOREIGN KEY(SITE_ID) REFERENCES SITE(SITE_ID));


   
2. DML 명령
 - 데이터 조작에 관련한 SQL 명령
 - INSERT, DELETE, UPDATE 문이 이에 속함 
 -- INSERT(삽입) : 대상테이블에 해당자료가 존재하지 않아야 함 

    (머지 : 있는 데이터 자료로 수정할수 있음/하지만 잘 안쓴다.)
 1) INSERT
   . 테이블에 자료를 삽입하는 명령 --해당자료가 중복디면 안된다.
(사용형식)
 INSERT INTO 테이블명[(컬럼명[,컬럼명,.....])] --insert into 작업에 대상이되는 컬럼명을 쓰고 //2개의 절로 됨
  VALUES(값,[값,....]);
     - '(컬럼명[,컬럼명,.....])' 이 생략되면 설계시 정의한 컬럼의 순서와 갯수에 맞도록
        VALUES절의 '값'이 기술되어야 함.
     - '(컬럼명[,컬럼명,.....])'은 모든 컬럼에 값을 정의하지 않고 일부 컬럼에만 값을
        입력하고자 하는 경우 사용
     - '(컬럼명[,컬럼명,.....])' 사용시 컬럼의 제약조건 중'NOT NALL' 컬럼은 생략 불가능
     - '(컬럼명[,컬럼명,.....])' 의 컬럼순서와 갯수에 맞도로 VALUES절의 값이 기술되어야 함
     -
     
사용예) 다음 자료를 사원테이블에 저장하시오


 --    DEPT_NAME  VARCHAR2(50)을 (10)으로 바꿨을때       
 --    INSERT INTO EMP VALUES('S101','홍길동','공공사업팀 1팀','010-1234-5678'); 
 --    오류 컬럼 저장 데이터 공간보다 데이터 입력값이 더 큼

    INSERT INTO EMP VALUES('S101','홍길동','공공사업팀 1팀','010-1234-5678'); 
    --1행이 삽입되었습니다.
    SELECT * FROM EMP; -- 모든 EMP행을 출력해주세요


    INSERT INTO EMP(DEPT_NAME,EMP_NAME,EMP_ID)
           VALUES('국내영업부','이순신','E202');
        
    SELECT * FROM EMP; --사용자가 입력하지 않은 값은 NULL
    
    INSERT INTO EMP VALUES('S104','강감찬','','042-000-8200');
    --컬럼명이 생략됐을때 VALUES값 /'부서명' => NULL & ' '<< 공백도 됨
    --오류일때 : not enough values 값이 부족합니다.
    
    INSERT INTO EMP VALUES('S105',' ','공공사업팀 2팀',' ');
  
    SELECT * FROM EMP;

    --오류 : cannot insert NULL into ("LHY93"."EMP"."EMP_NAME") 

                 EMP_NAME 설계할때 값 not null이여서
    --EMP_NAME에 공백' ' >> 저장됨. 공백도 데이터이다. >>null값이 아님.

 



 2) UPDATE --  변경
   . 테이블에 존재하는 자료를 대상으로 수정작업 수행
   (사용형식)
    UPDATE 테이블명
        SET (컬럼명[,컬럼명,...]) = (값[,값,...])[,]
                            .
                            .
            [(컬럼명[,컬럼명,...]) = (값[,값,...])]
    [WHERE 조건]; --생략될수 있음(행에 관련된것) //SELECT절은 열에 관련
    - '테이블명' : 갱신 대상 테이블명
    - (컬럼명[,컬럼명,...]) : 변결할 컬럼명 기술하며 보통 하나의 컬럼명을 기술하나
      복수개의 컬럼 값을 동시에 변경 하고자 하는 경우 '( )' 안에','로 분리하여
      컬럼을 기술하고'=' 다음에 같은 갯수와 순서에 맞는 '값'을 기술하거나
      Subquery를 사용하여 값을 설정한다.
      
    - 'WHERE 조건' : 변경할 자료를 선택하기 위한 조건이며, 생략하는 경우 모든 행의 값이 변경됨
    
사용예) 강감찬 사원의 부서명을  '공공사업 2팀'으로 수정하시오 (이미 NILL값이 들어있음. (행단위))

UPDATE EMP
   SET DEPT_NAME='공공사업 2팀'; --4개의 행이 업데이트 되었습니다.
   
SELECT * FROM EMP;
    
ROLLBACK; -- COMMIT을 안해서 자료가 다 삭제됨.


--------------------------------------------------------------------------------

    INSERT INTO EMP VALUES('S101','홍길동','공공사업팀 1팀','010-1234-5678'); 

    INSERT INTO EMP(DEPT_NAME,EMP_NAME,EMP_ID)
           VALUES('국내영업부','이순신','E202');
    
    INSERT INTO EMP VALUES('S104','강감찬','','042-000-8200');
      
    INSERT INTO EMP VALUES('S105',' ','공공사업팀 2팀',' ');
    
    SELECT * FROM EMP;
    COMMIT; --다시 삽입 후 COMMIT;


----------------------------------오류----------------------------
 /* UPDATE EMP
        SET DEPT_NAME='공공사업 2팀'
  WHERE EMP_ID='S104';
  --4개의 행이 업데이트 되었습니다.
 --선택할 행의 컬럼명='강감찬'이어야함*/

-----------------------------------------------------------------------
 
 사용예)사원번호 'S105' 사원의 사원명을 '홍길순'으로, 전화번호를 '010-0000-6543'수정하시오

 UPDATE EMP
    SET EMP_NAME='홍길순',
        TEL_NUM='010-0000-6543'
  WHERE EMP_ID='S105';
 
  UPDATE EMP
     SET (EMP_NAME,TEL_NUM)=(SELECT '홍길순','010-0000-6543'
                               FROM DUAL) --쿼리안에 쿼리가 있음 =서브쿼리 / DUAL 가상의 뷰
   WHERE EMP_ID='S105';
      
   SELECT * FROM EMP
    ORDER BY EMP_ID; -- 사용되어질 열번호 기준으로 정렬
    COMMIT;

 


  
     
 3) DELETE 
    - 저장된 데이터 삭제
    - ROLLBACK의 대상


  (사용형식)
  DELETE FROM 테이블명
    [WHERE 조건]
    - 'WHERE 조건' 이 생략되면 테이블의 모든 자료 삭제(테이블은 존재)


** TRUNCATE 명령
    - 테이블의 모든 자료 삭제(테이블은 존재)
    - ROLLBACK 되지 않음
    - 개별적 자료삭제는허용 안됨


  (사용형식)
   TRUNCATE TABLE 테이블명;
   
사용예) 사원테이블에서 '홍길동'사원을 삭제하시오.

 DELETE 
   FROM EMP
  WHERE EMP_NAME='홍길동'; --삭제
  
SELECT * FROM EMP;
    
ROLLBACK;
    
 DELETE 
   FROM EMP; --제목만 출력됨 : 자료가 없다. 쿼리의 문제는 없는데 자료가 없다.
ROLLBACK;
    
TRUNCATE TABLE EMP; 
--오류 발생.테이블에 왜래키를 참조하고 있어서 삭제가 안됨. 참조하는 왜래키를 모두 삭제하고 해야함
-- 결과는 테이블의 구조는 남아있지만 자료만 없음
-- 제일 하위에 있는 테이블만 적용된다


    
*** 테이블 삭제 DROP
    - DROP 명령 사용


 (사용형식)
    DROP TABLE 테이블명;
    
   -- 여러개의 테이블을 동시에 삭제하고 싶다 => 보통 쿼리로 처리안됨. -- 하나씩 나열해야함.
   -- 관계가 설정된 테이블은 자식테이블 부터 삭제 되어야 함.

   -- 참조무결성 위배가 되기 때문에 - 프로그램에서 삭제 불가
   -- 자식테이블부터 삭제하는 방법(보편적) , 관계를 다 삭제함 (ARLT 명령어)


사용예)

    DROP TABLE SITE; --참조하는 왜래키가 삭제
    DROP TABLE SITE_MAT;
    DROP TABLE WORK_TBL;
    DROP TABLE WORK_TBL2;
    DROP TABLE EMP;
    DROP TABLE SITE; -- 새로고침하면 삭제됨.


    
    
    
    
 

Oracle SQL - 데이터 검색명령(SELECT)

 

 - 필요한 자료를 검색하기 위한 명령


  (사용형식)
  SELECT [*|[DISTINCT]] 컬럼명 [AS 별칭] [,]
         [컬럼명[AS 별칭]][,]
                .
                .
         [컬럼명[AS 별칭]][,]  
    FROM 테이블명 --가상의 뷰도 할 수 있음 --왼쪽 메뉴의 '뷰' = 이름이 있는 뷰 
         -- 서브쿼리 실행 => 결과는 뷰
  [WHERE 조건]
  [GROUP BY 컬럼명[,컬럼명,....]]
 [HAVING 조건]
  [ORDER BY 컬럼명 컬럼 IDEX [ASC|DESC] [,컬럼명/컬럼INDEX [ASC|DESC],...]];


   . 'DISTINCT' : 중복자료를 배제시킴, 하나의 컬럼에만 기술, 나머지 컬럼도 고려하여 중복 배제
   . 'AS 별칭' : 컬럼제목 또는 서브쿼리에서 컬럼값을 참조할 때 사용
    - '별칭'에 특수문자(공백 등)를 사용할 경우 반드시 컬럼명을 " "로 묶어야 함
   . 'ORDER BY 컬럼명ㅣ컬럼INDEX': 정렬 기준 컬럼 설정, 컬럼명이나 컬럼의 기술 순번 기술
   . ASC : ASCENDING,(오름차순, DESC : DESCENDING(내림차순)
   . 실행순서 : FROM 절 => WHERE 절 => SELECT 절
   
   -- 테이블 존재 => 조건 검색해서 출력할 행 찾음 => 결과 SELECT 컬럼 출력. 

      마지막 컬럼에는 콤마가 없어야함

   
 

 SELECT DISTINCT CART_MEMBER AS 회원번호, 
                 CART_NO AS "장바구니 번호" 
 -- 별칭의 사용 가능 길이는 =30글자까지 쓸수 있음
   FROM CART
  ORDER BY 1;
    
  SELECT DISTINCT CART_MEMBER AS 회원번호,
                  CART_NO AS "장바구니 번호" 
    FROM CART
   WHERE '회원번호=a001' --WHERE절에서는 한글 회원번호를 인식할수 없음
  ORDER BY 회원번호;
    
 SELECT CART_MEMBER AS 회원 번호 --오류 공백 때문에 안끝난것으로 본다.
    FROM CART;

    

 



1. 데이터 타입

 - 오라클에서 사용되는 데이터 타입에는 문자열, 숫자, 날짜, 2진 데이터타입이 제공
  1) 문자열 자료타입
   . 문자열은 ' '안에 표현되며 대소문자를 구별함
   . 문자열을 저장하는 자료 타입은 CHAR, VARCHAR, VARCHAR2, NVARCHAR2, LONG, CLOB, NCLOB
     등이 제공되며 N으로 시작되는 데이터 타입은 국제표준어로 저장할때 사용

     (UTF-8, UTF-16방식으로 저장)


    (1) CHAR (n [BYTE|CHAR])
     . 고정길이 문자열 저장
     . 최대 2000BYTE 까지 저장 가능
     . 데이터가 확보된 기억공간보다 작으면 기억공간 오른쪽에 공백삽입
     . 한글은 1글자가 3BYTE 이며 최대 666글자까지 저장 가능
     . '[BYTE|CHAR]' : n 이 BYTE인지 CHAT(글자수)인지를 설정하며 생략하면 BYTE로 간주
 
 
 사용예) -- 고정길이

CREATE TABLE TEMP01 (
        COL1 CHAR(10),
        COL2 CHAR(10 BYTE),
        COL3 CHAR(10 CHAR)); -- 10글자 저장
        
        
    INSERT INTO TEMP01 VALUES('대전시','대전시','대전시');
    
    SELECT * FROM TEMP01;
    
    SELECT LENGTHB(COL1) AS "컬럼1", -- 10BYTE (대전시 9바이트 + 공백 1바이트)
           LENGTHB(COL2) AS "컬럼2", -- 10BYTE (대전시 9바이트 + 공백 1바이트)
           LENGTHB(COL3) AS "컬럼3" -- 16BYTE (대전시3글자/ 9바이트 + 공백7글자/ 7바이트)

                                                            = 10글자/ 16(9+7)바이트
        FROM TEMP01;
    -- LENGTH : 글자수 출력 / LENGTHB : 글자수 바이트 출력
    -- CHAR(10 CHAR)); 거의 안쓴다.

 
 
    (2) VARCHAR2 (n [BYTE|CHAR])
     . 가변길이 문자열 저장
     . 최대 4000BYTE 저장 가능
     . VARCHAR와 동일 방식으로 문자열 저장(VARCHAR2)는 오라클에서만 사용

사용예)--VARCHAR2는 오라클에서만 사용한다.
 

 CREATE TABLE TEMP02(
        COL1 VARCHAR2(20),
        COL2 VARCHAR2(20 BYTE),
        COL3 VARCHAR2(20 CHAR));
 
    INSERT INTO TEMP02 VALUES('대전시 중구','대전시 중구','대전시 중구'); 
    
    SELECT * FROM TEMP02;

※ 데이터를 저장하다가 기억공간이 부족하면 오류/ 남으면 운영체제에 반납한다.
운영체제에게 반납한다 : 그 기억공간이 이 프로그램에서 사용하지 않고,
    다른 프로그램의 다른사람이 쓸수 있도록 점유 해제 한다.
    
    

SELECT LENGTHB(COL1) AS "컬럼1", -- 16BYTE
       LENGTHB(COL2) AS "컬럼2", -- 16BYTE 
       LENGTHB(COL3) AS "컬럼3" -- 16BYTE
  FROM TEMP02;
 --'대전시 중구' : 15 + 1(공백) = 16바이트


    (3) LONG --자바의 LONG : 정수형(숫자) 타입 / 오라클 LONG : 문자열 타입
     . 가변길이 테이터 타입
     . 최대 2GB 까지 저장 가능
     . 한 테이블에 하나의 LONG타입만 선언 가능(단점) => CLOB로 보완
     . 사용가능하나 기능 개선 서비스는 중단
     . 사용가능한 곳으로,  SELECT문의 SELECT절, UPDATE문의 SET절,
       INSERT문의 VALUES절
     -- 사용하지 않도록 권고합니다.
     -- CLOB 보완점 : 4000바이트 이하면 LENGTHB 사용 가능 
    
사용예)

CREATE TABLE TEMP03(
        COL1 LONG, --길이를 나타내는 매개변수가 없다.
        COL2 VARCHAR2(4000),
        COL3 LONG); -- 롱타입 2개 이상
--오류 한테이블에 롱타입 컬럼을 하나만 쓸수 있다.
    
CREATE TABLE TEMP03(
        COL1 LONG, 
        COL2 VARCHAR2(4000),
        COL3 CLOB);
    INSERT INTO TEMP03 VALUES('대전시중구 계룡로 000','Oracke SQL',
                              '대전시중구 계룡로 000 00인재개발원 300호');                          
    SELECT * FROM TEMP03;
    
    SELECT -- LENGTHB(COL1) AS "컬럼1"
              LENGTHB(COL2) AS "컬럼2"         
           -- LENGTHB(COL3) AS "컬럼3" -- LENGTH 는 사용가능 / LENGTHB 안됨
      FROM TEMP03;
        
    SELECT  --LENGTH(COL1) AS "컬럼1", 오류 -- 기능개선을 안해줘서 안됨
              LENGTH(COL2) AS "컬럼2",         
              LENGTH(COL3) AS "컬럼3" -- 4000바이트 이내이면 됨. 

    -- 과거 : DBMS_LOB.GETLENGTH(COL3) 적용
      FROM TEMP03;
    -- LENGTH : 글자수 출력 / LENGTHB : 글자수 바이트 출력

   
    
    (4) CLOB(Character Large OBject)
      . 가변길이 데이터 타입
      . 최대 4GB 까지 저장 가능
      . LONG타입을 개선한 자료형
      . 일부 기능(크기나 위치값을 이용하는 기능)은 DBMS_LOB API의 지원을 받아야 함
    
사용예)

CREATE TABLE TEMP04(
        COL1 CLOB,
        COL2 CLOB,
        COL3 VARCHAR2(4000));
    
INSERT INTO TEMP04 VALUES('PERSIMMON APPLE BANANA', --1글자가 1번 // 자바는 1글자가 0번
                          'PERSIMMON APPLE BANANA',  --5       10--
                          'PERSIMMON APPLE BANANA'); --IMMON APPL--
                              
SELECT * FROM TEMP04;
    
SELECT DBMS_LOB.GETLENGTH(COL1),
           LENGTH(COL1),
           SUBSTR(COL2,5,10), 
--SUBSTR : SUBSTRING : 5번째 글자부터 10번째 글자까지 추출하세요
           DBMS_LOB.SUBSTR(COL2,5,10) 

--10번째 글자에서 5번째 글자(개수)까지 추출하세요 기능이 뒤바뀜??
  FROM TEMP04;


    

Oracle SQL - 숫자 자료, 날짜 자료


 2) 숫자 자료 타입
  . 정수 및 실수를 저장
  . NUMBER타입 제공
  . 저장범위 : 1.0 X 10^-130 ~ 9.99....99 X 10^125 (소수점이하 38자리까지 허용)
  --          제일 작은수    ~   약 1.0 X 10^126
  
  
(사용형식)
  컬럼명 NUMBER([정밀도|*][,스케일]) -- * : 1.0 X 10^-130 ~ 9.99....99 X 10^125 범위의 수 알아서 생성
   . 정밀도 : 전체 자리수 의미(I ~ 30)
   . 스케일 소숫점이하의 자리수
   . 저장은 스케일이 양수인 경우 : '스케일 + 1'번째 자리에서 반올림하여 '스케일'자리까지 저장
           스케일이 음수인 경우 : 정수 부분 '스케일' 위치에서 반얼림
   . 정수부분이 데이터 보다 작으면 오류
   . 스케일이 생략되면 0으로 간주
   . 정밀도예 '*'가 사용되면 전체 크기를 시스템에게 위임하여 가장 효율적인 크기를 배정 받음
     
 선언예) 
  컬럼명 NUMBER -- 사용자가 입력한 값을 그대로 저장한다. 
  컬럼명 NUMBER(*,3) -- * : 컴퓨터가 알아서 숫자 자리 처리함
  컬럼명 NUMBER(6) -- 스케일값 생략 : 0 으로 간주/소숫점을 없앤다. =(6.0)
  컬럼명 NUMBER(6,2) -- 일반적 사용 형태 : 소숫점이하3번째에서 반올림하고 정수부분은 4자리이다.
  컬럼명 NUMBER(6,0)
  컬럼명 NUMBER(6,-2)
  
  
  
--< 형 식 >
--NUMBER(10,2) : 12345.6789102 

(소숫점 이하 순서 양수로 저장됨 : 123 / 양수는 소숫점 기준으로 음수순번)
--                       -5-4-3-2-1.1234567 <<자리번째 (정수5개+소숫점이하7 = 5+7 =12)
--NUMBER(12,2) << 맞는 표현
--NUMBER(전체자리 : 소숫점이하 포함,~번째 자리에서 반올림: 양수인경우 N+1자리부터/음수인경우 N번째자리)
-- 정밀도~ 스케일 생략가능함 : (1.0 X 10^-130 ~ 9.99....99 X 10^125) 범위 내
  
  
  
  사용예)
  ---------------------------------------------------------------------------------------------
  입력값                     선언                     기억되는 형태
  ---------------------------------------------------------------------------------------------
  1234.56789        NUMBER                   1234.56789
  1234.56789        NUMBER(*,2)            1234.57  --반올림 소수자리3         
  1234.56789        NUMBER(6)               1235--소수첫째자리에서 반올림함 1234.5<<
  1234.56789        NUMBER(5,2)             오류 -- 소수자리3에서 반올림 하는데 전체값은 '1234.57' 6자리이다
  1234.56789        NUMBER(6,2)             1234.57
  1234.56789        NUMBER(6,0)             1235
  1234.56789        NUMBER(6,-2)            1200 -- 1234에서 3에서(-2자리) 반올림 1200
  

    CREATE TABLE TEMP05(
        COL1 NUMBER,
        COL2 NUMBER(*,2),
        COL3 NUMBER(6),
        COL4 NUMBER(5,2),
        COL5 NUMBER(6,2),
        COL6 NUMBER(6,0),
        COL7 NUMBER(6,-2));


     

    INSERT INTO TEMP05 VALUES(1234.56789,1234.56789,1234.56789,
                              123.56789,1234.56789,1234.56789,1234.56789);
    -- 오류보고 precision : 정밀도 : 더 큰값이 들어왔습니다.
    -- COL4 NUMBER(5,2) => 4번째 값 : 123.57 // '123.56789' 

    => 소숫점 3자리에서 반올림하고 전체 숫자는 5자리이다
    
    SELECT * FROM TEMP05;

    
    
 3) 날짜 자료 타입
  . 날짜자료(년,월,일,시,분,초) 저장 -- YYYY-MM-DD HH24:MI:SS 14자리
  . DATE, TIMESTAMP 타입 제공

 -- TIMESTAMP : 십억분의 일초 까지저장가능 / 3가지 타입이 있음 // 보통은 DATE 타입 사용
 -- 둘다 크기지정 안한다.
  
  
   (1) DATE 타입
    . 기본날짜 자료형
    . 덧셈(다가올 날짜)과 뺄셈(지나간 날짜)의 대상이 됨
    .  **SYSDATE : 날짜함수로 (지금 시스템이 제공하는) 시스템의 날짜 및 시각 정보를 반환 

    -- 매개변수가 없는 함수. 
    -- 함수는 매개변수가 없으면() 괄호 생략한다.
    -- 날짜로 인식시키는 방법 : YYYY년,MM월,YY일
    -- 날짜형 기억공간에 숫자를 저장함 20200229 윤년이면 되고 윤년이 아니면 오류


사용형식)
    컬럼명 DATE 
    

사용예)

CREATE TABLE TEMP06(
        COL1 DATE, -- 크기 지정안한다.
        COL2 DATE,
        COL3 DATE);
      
    INSERT INTO TEMP06 VALUES(SYSDATE,SYSDATE-10,SYSDATE+10);
    --                  오늘날짜, 오늘날짜 -10일전, 오늘날짜 +10일후 //윈도우 시스템 시간확인
    -- 곱셈 안되고 덧셈, 뺄셈만
    
    SELECT * FROM TEMP06;

   
-- 시분초도 저장되어 있는데 컬럼에 안보임 -> 시분초까지 출력하기 위해서는 별도의 함수가 필요함 

**시간정보 표시는 TO_CHAR 함수 사용 --변환 함수 

SELECT TO_CHAR(COL1,'YYYY-MM-DD HH24:MI:SS'), -- 13시 HH24  = 1시 HH12
       TO_CHAR(COL2,'YYYY-MM-DD HH24:MI:SS'),
       TO_CHAR(COL3,'YYYY-MM-DD HH24:MI:SS')
  FROM TEMP06;

-- 출력 : 2022-11-10 12:15:55



-- 중요!↓
날짜자료 사이의 뺄셈은 두 날짜사이의 일수(DAYS)를 반환

    SELECT case mod(to_date('19991111')-TO_DATE('00010101')-1,7) -- 목요일
                when 0 then '일요일'
                when 1 then '월요일'
                when 2 then '화요일'
                when 3 then '수요일'
                when 4 then '목요일'
                when 5 then '금요일' 
                when 6 then '토요일'
            end as 요일
        FROM DUAL;                                    
    -- 출력 : 5 오늘은 금요일입니다.
    -- mod는 7나눈 나머지 = 0이면 일요일
    -- 오늘날짜에서 00010101 빼줌 ; 오늘은 아직 안지나서 -1을 해준다. -> 7로 나누고 나머지를 반환하세요
    -- => 5라는 값 => 금요일 판단.


    
   (2) TIMESTAMP 타입
     . 매우 정교한 시각정보가 필요하거나 시간대역(TIME ZONE) 정보가 필요한 경우 사용

(사용형식)
    컬럼명 TIMESTAMP -- 시간대역 정보없이 10억분의 1초 시각정보 반환
    컬럼명 TIMESTAMP WITH LOCAL TIME ZONE 

-- 로컬서버가 위치한 지역(현재 로그인된 지역)의
   시간대역정보(생략 됨)와 10억분의 1초 시각정보 반환
    컬럼명 TIMESTAMP WITH TIME ZONE 

-- 서버가 위치한 시간대역정보(생략 됨)와 10억분의 1초 시각정보 반환

사용예)

CREATE TABLE TEMP07(
        COL1 TIMESTAMP, -- 매우정교함 표로 보여질때는 소숫점자리가 짤림.
        COL2 TIMESTAMP WITH LOCAL TIME ZONE, -- (시간대역정보)생략 COL1과 거의 같음
        COL3 TIMESTAMP WITH TIME ZONE); -- ASIA / SEOUL 

        // 윈도우시스템- 시간및 날짜 : (UTC +  ) 서울
                            --         대륙명 / 도시            
    INSERT INTO TEMP07 VALUES(SYSDATE,SYSDATE,SYSDATE);
    
    SELECT * FROM TEMP07;




Oracle SQL - 기타자료형


 - 2진 자료(이미지, 동영상, 음성 등의 자료)를 저장하기 위한 데이터 타입 --멀티미디어 자료
 - RAW, BFILE, BLOB 타입 제공
 - 모든 이진자료는 오라클에서 해석하거나 변환하지 않음 
  
--  아날로그데이터를 디지털 타입으로 ->사진 -> 0과1로 /사진 : JPG, PNP 확장자 : 변환 알고리즘
  

1. RAW 타입 --초기 제공 데이터 타입 --저장하는 능력이 제한되어있다.
  . 매우 작은 크기의 이진자료 저장
  . 최대 2000BYTE까지 저장가능 -- 2kb => 너무 작아서 거의 안씀
  . 인덱스 처리 가능 -- 크기가 작기 때문에 특정한 데이터를 빠르게 찾기 가능.
  . 16진수와 2진수 형태로 저장
  
  
사용형식)
    컬럼명 RAW(크기)

(사용예)

    CREATE TABLE TEMP08(
           COL1 RAW(2000));
    
    INSERT INTO TEMP08 VALUES(HEXTORAW('3DA8FF97')); 

    --핵사 : 16진수 / 2진수 : 바이너리// 16진수를 RAW타입으로 저장하세요
    INSERT INTO TEMP08 VALUES('001 11101 1010 1000 1111 1111 11 0010111'); --대충씀
    INSERT INTO TEMP08 VALUES('3DA8FF97');
    
    SELECT * FROM TEMP08;

    

2. BFILE 타입 -- 사진이나 동영상을 주로 사용
  . 이진자료를 저장
  . 원본자료는 데이터베이스 밖에 저장하고 데이터베이스에는 파일명과 경로(Path)만 저장
  . 최대 4GB까지 저장가능

-- 테이블안에는 실제 그림이 저장된게 아니라 경로와 파일명만 들어감



사용형식)
    컬럼명 BFILE;

사용예)
    CREATE TABLE TEMP09(
        COL1 BFILE);
    
    
**BFILE 타입으로 사진을 저장하는 방법

더보기

     1) 사진 준비(jpg 타입) --sample.jpg
     2) 디렉토리객체 생성--왼쪽 메뉴 하단에 '디렉토리'
      . 파일명은 256BTYE, 디렉토리명(별칭:Alias)은 30BYTE까지 허용 -- << 윈도우의 경우에
-- 디렉토리 생성     
    CREATE DIRECTORY 디렉토리 별칭 AS '경로명'; 
    CREATE DIRECTORY TEST_DIR AS 'D:\A_TeachingMaterial\02_Oracle'; 

   --Directory TEST_DIR이(가) 생성되었습니다.
      
     3) 데이터 삽입
     INSERT INTO TEMP09 VALUES(BFILENAME('TEST_DIR', 'sample.jpg')); 

     --함수 BFILENAME 입력

     SELECT * FROM TEMP09;

      --함수 BFILENAME 입력 - > 디렉토리 / 경로가 결정되어있어야함
      --입력을 하고 테이블생성하면 -> 이미지 그래픽 표현은 자바에서 표현 가능하다.
     
  
-- 테이블이 공간 마련되어있다
-- 집어넣을 사진이 필요하다(오라클에서 많이사용하는 JPG타입 사진)
  
  
3. BLOB(Binary Large OBject) 타입
  . 이진자료 저장을 위한 자료타입
  . 원본자료를 직접 테이블 내부에 저장
  . 최대 4GB까지 처리 가능
  
사용형식)
    컬럼명 BLOB
    
-- INSERT로 저장할수 없음 별도의 변수함수 사용 PROCESS : 반환 값이 없음 / BLOCK 이용


**BLOB 타입으로 자료저장 PROCESS

더보기


    1) 테이블 생성
    
    CREATE TABLE TEMP10(
        COL1 BLOB);
    
    2) 자료파일 및 디렉토리 및 생성 --sample.jpg / 디렉토리 : TEST_DIR
    sample.jpg, TEST_DIR
    
    3) 저장을 위한 BLOCK(PL/SQL의 익명블록 또는 프로시져) 생성
    DECLARE --익명블록 : 이름이 없음 , 저장안됨
        L_DIR VARCHAR2(30):='TEST_DIR';  --- 변수 선언 ':=' 대입연산자
        L_FILE VARCHAR2(255):='sample.jpg';
        L_BFILE BFILE;
        L_BLOB  BLOB;  
    BEGIN
        INSERT INTO TEMP10(COL1) VALUES(EMPTY_BLOB()) -- 빈공간을 채울때 쓰는 함수
            RETURN COL1 INTO L_BLOB;
        
          L_BFILE:=BFILENAME(L_DIR,L_FILE); ------------------ 파일을 만들어라
          DBMS_LOB.FILEOPEN(L_BFILE,DBMS_LOB.FILE_READONLY);-- 파일을 열어라 : sample.jpg(읽기전용)
          DBMS_LOB.LOADFROMFILE(L_BLOB,L_BFILE,DBMS_LOB.GETLENGTH(L_BFILE));

        -- 읽기 : 파일의 크기를 반환
          DBMS_LOB.FILECLOSE(L_BFILE);      ------------------ 더이상 쓸일이 없다 : 파일을 닫아라
    
        COMMIT;
    END;

    SELECT * FROM TEMP10;

-- TEMP10 테이블의 COL1컬럼에 BLOB 파일로 저장

  
  
  
  
  
  
  
  

DROP TABLE TEMP01;
DROP TABLE TEMP02;
DROP TABLE TEMP03;
DROP TABLE TEMP04;
DROP TABLE TEMP05;
DROP TABLE TEMP06;
DROP TABLE TEMP07;
DROP TABLE TEMP08;
DROP TABLE TEMP09;
DROP TABLE TEMP10;
COMMIT;

-- 만들었던 테이블 지우기

Oracle SQL - 연산자

 


 - 오라클에 사용되는 연산자는 산술, 관계, 논리
 - 산술연산자 : +, -, /, *, (나머지 연산자는 제공되지 않음: 함수로 제공) 


사용예) HR 계정의 사원테이블(EMPLOYEES)에서 사원들의 급여와(SALARY) 

--출력할 열 => 전체직원 다 출력(WHERE 생략)
        영업실적코드(COMMISSION_PCT)로 보너스를 계산하고 지급액을 출력하시오
        보너스 = 기본급여(SALARY)* 영업실적코드(COMMISSION_PCT)
        지급액 = 기본급여(SALARY) + 보너스
   (별칭)Alias는 사원번호,사원명,기본급여,보너스,지급액

   

SELECT EMPLOYEE_ID AS 사원번호,
       FIRST_NAME||' '||LAST_NAME AS 사원명, -- ||' '|| 문자열 붙이기
       SALARY AS 기본급여,
       NVL(SALARY*COMMISSION_PCT,0) AS 보너스,
       SALARY+NVL(SALARY*COMMISSION_PCT,0) AS 지급액      
-- 변수가 없어서 항목을 붙여서 써야함
  FROM HR.EMPLOYEES;
-- 계정은 HR이니까 꼭 계정명 확인해서 써줘야함!!

       
    -- 기본급여는없는데 영업실적이 없어서 보너스, 지급액 = 0
    -- 해결하기 위해 NVL( , 0) => 보너스는없어도 지급액이 나온다.
 


 - 관계연산자 : 자료의 크기를 판단하는 연산자로 결과가 true과 false로 조건문 구성에 사용(WHERE절)
                         >, <, =, >=, <=, !=(<>)          ---- (><) 이거는 안된다.(오라클에서)   

                       
사용예) 회원테이블에서 (조건)마일리지가 3000이상인 회원의 회원번호,회원명,주소,직업,마일리지를 조회하시오.
       단, 마일리지가 많은회원부터 출력하시오(정렬,내림차순)

더보기

    SELECT MEM_ID AS 회원번호,
                   MEM_NAME AS 회원명,
                   MEM_ADD1||' '||MEM_ADD2 AS 주소,--기본주소+상세주소 <<' ' 사이에 공백 입력
                   MEM_JOB AS 직업,
                   MEM_MILEAGE AS 마일리지
      FROM MEMBER
   WHERE MEM_MILEAGE>=3000      -- 마일리지가 3000이상
--  ORDER BY MEM_MILEAGE DESC;-- ORDER BY 정렬 마일리지 내림차순
 ORDER BY 5 DESC;                         -- 5번째 컬럼//SELECT 절에서 몇번째에 나왔는지?(나온순번 5)

                                                               자바와 다르게 1번 부터 시작

                                                                  

사용예) 상품테이블에서 판매가가 50만원이상인 상품을 조회하시오.
        Alias는 상품코드,상품명,매입가,판매가,적정재고
             

더보기

 SELECT PROD_ID AS 상품코드, 
                    PROD_NAME AS 상품명,
                    PROD_COST AS 매입가,
                    PROD_PRICE AS 판매가,
                    PROD_TOTALSTOCK AS 적정재고
       FROM PROD
    WHERE PROD_PRICE>=500000;

 


**컬럼추가 및 변경(이름,데이터타입)
 1) 컬럼추가 사용형식
  ALTER TABLE 테이블명 ADD(컬럼명 데이터타입[(크기)]) [NOT NULL] [DEFAULT 값]);

사용예) HR 계정의 사원테이블(EMPLOYEES)에 사원명(EMP_NAME)컬럼을 

            문자열 80BYTE로 삽입하시오
       ALTER TABLE HR.EMPLOYEES ADD(EMP_NAME VARCHAR2(80));

사용예) 사원테이블의 FIRST_NAME과 LAST_NAME을 결합하여(중간에 공백 삽입) 

             EMP_NAME에 저장하시오   
    UPDATE HR.EMPLOYEES
        SET EMP_NAME=FIRST_NAME||' '||LAST_NAME;
    
    SELECT EMP_NAME FROM HR.EMPLOYEES;
    
    COMMIT;
        
 2) 컬럼 수정
  (1) 속성 수정
    ALTER TABLE 테이블명 MODIFY(컬럼명 데이터타입[(크기)]) [NOT NULL] [DEFAULT 값]);     
    
 3) 컬럼 이름변경
    ALTER TABLE 테이블명 RENAME COLUMN old_name TO new_name;

 4) 컬럼 삭제
    ALTER TABLE 테이블명 DROP COLUMN 컬럼명;
    
    

사용예) 사원테이블에서 입사일이 2007년 이후인 사원들을 조회하시오
        Alias는 사원번호,사원명,부서코드,직무코드,입사일

더보기

  SELECT EMPLOYEE_ID AS 사원번호,
                   EMP_NAME AS 사원명,
                   DEPARTMENT_ID AS 부서코드,
                   JOB_ID AS 직무코드,
                   HIRE_DATE AS 입사일
       FROM HR.EMPLOYEES
--  WHERE HIRE_DATE>'20070101'; -- 날짜 검색 FROM 테이블이름 WHERE 컬럼이름>'숫자 문자열';
--   HIRE_DATE>='2007/01/01'; '날짜타입' 관계연산 '문자열'=>DATE타입으로 형변환됨. 비교대상의 타입을 확인!
    WHERE TO_CHAR(HIRE_DATE,'YYYYMMDD')>='20070701';
--  WHERE TO_CHAR(HIRE_DATE,'YYYYMMDD')>'20070701';

 

- 20대인지-> 나이를 구함/주민번호 앞자리 이용 20보다 크고 30보다 작아야함

사용예) 회원테이블에서 여성회원이면서 20대인 회원들을 조회하시오            

-- 주민등록 2번째자리의 첫글자 2 이거나 4 'OR'연산자 
        Alias는 회원번호,회원명,주민번호,나이,,마일리지

더보기

SELECT MEM_ID AS 회원번호,
           MEM_NAME AS 회원명,
           MEM_REGNO1||'-'||MEM_REGNO2 AS 주민번호,
           CASE WHEN SUBSTR(MEM_REGNO2,1,1) IN('3','4') THEN
                     EXTRACT(YEAR FROM SYSDATE)-(2000+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2)))

                      --오늘날짜 -(빼기) 주민번호 첫번째의 2자리
           -- 첫번째 주민등록번호 에서 1번째글짜에서 2번째 글짜까지를 뗀다. + 2000년 
           -- 이것을 오늘날짜에서 빼준다.
           -- SUBSTR 결과는 '문자열이다.'
                ELSE
                    EXTRACT(YEAR FROM SYSDATE)-(1900+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2)))
           END AS 나이,
           MEM_MILEAGE AS 마일리지
    FROM MEMBER

    --  WHERE 나이<=20 AND 나이 <=29; / (나이 BETWEEN 20 AND 29;)--<< 이렇게 못쓴다.
    -- FROM절 먼저 실행되고 WHERE절 실행 => SELECT 절 실행되기 때문에 위엣줄은 실행 안됨.

 

WHERE  TRUNC(CASE WHEN SUBSTR(MEM_REGNO2,1,1) IN('3','4') THEN
                       EXTRACT(YEAR FROM SYSDATE)-(2000+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2))) 

                       --오늘날짜 - 주민번호 첫번째의 2자리
                 ELSE
                       EXTRACT(YEAR FROM SYSDATE)-(1900+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2)))
           END,-1) = 20 -- TRUNC 다 짤라진게 20과 같아야 함
           ORDER BY 나이; -- ORDER BY절은 SELECT 절 수행후 실행되기때문에 나이 별칭 사용가능
          
    
/*    WHERE  CASE WHEN SUBSTR(MEM_MEM_REGNO2,1,1) IN('3','4')  THEN
                     EXTRACT(YEAR FROM SYSDATE)-(2000+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2))) 

                ELSE
                    EXTRACT(YEAR FROM SYSDATE)-(1900+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2)))
           END <=20;
                    EXTRACT(YEAR FROM SYSDATE)-(2000+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2)))

                     
                ELSE
                    EXTRACT(YEAR FROM SYSDATE)-(1900+TO_NUMBER(SUBSTR(MEM_REGNO1,1,2)))
           END <=29;
           
           END AS 나이, 
           MEM_MILEAGE AS 마일리지 -- 모든 회원의 주민등록번호와 나이가 구해짐
        FROM MEMBER */
   



 - 논리연산자 : 복수개의 관계연산자를 결합할때 사용
                        NOT(논리부정), AND(논리곱), OR(논리합) -- NOT > AND > OR 우선순위 NOT이 제일 높다 
        --  NOT : 단항연산자(우선순위 높음) // 연산우선순위를 따지는 경우,
        
사용예) 회원테이블에서 보유마일리지가 3000-5000 인 회원정보 조회

            -- 구간은 AND / BETWEEN 연산자
       Alias는 회원번호,회원명,마일리지,직업

더보기

SELECT MEM_ID AS 회원번호,
             MEM_NAME AS 회원명,
             MEM_MILEAGE AS 마일리지,
             MEM_JOB AS 직업   
        FROM MEMBER
    WHERE MEM_MILEAGE>=3000 AND MEM_MILEAGE<=5000;
--  WHERE MEM_MILEAGE BETWEEN >3000 AND 5000;    // BETWEEN A AND B       


사용예) 회원테이블에서 거주지가 '대전'이 아닌 회원정보 조회 -- NOT 연산자 사용
       Alias는 회원번호,회원명,주소,전화번호

더보기

  SELECT MEM_ID AS 회원번호,
              MEM_NAME AS 회원명,
              MEM_ADD1||' '||MEM_ADD2 AS 주소,
              MEM_HOMETEL AS 전화번호
          FROM MEMBER
--     WHERE MEM_ADD1 NOT LIKE '대전%'; = 문자열 섞여있음 // '대전'으로 시작하는것 제외하고
--     WHERE NOT(MEM_ADD1 LIKE '대전%');
--     WHERE SUBSTR(MEM_ADD1,1,2)!='대전'; --MEM_ADD1 첫번째 글짜에서 2자를 떼라
       WHERE NOT(SUBSTR(MEM_ADD1,1,2)='대전');

 
사용예) 사원테이블에서 관리자번호가 없거나 100번인 사원의 사원번호,사원명,부서번호,급여를 조회하시오 
        --없거나(또는) OR /

더보기

SELECT EMPLOYEE_ID AS 사원번호,
               EMP_NAME AS 사원명,
               DEPARTMENT_ID AS 부서번호,
               SALARY AS 급여
            FROM HR.EMPLOYEES
        WHERE MANAGER_ID IS NULL OR MANAGER_ID=100 -- NULL값 조회하는 법 IS NULL!!
--      WHERE MANAGER_ID=NULL OR MANAGER_ID=100; => MANAGER_ID=NULL // '=' 안됨!!
        ORDER BY 3; -- 부서번호 순으로 


        
사용예) 매입테이블(BUYPROD)에서 2020년 2월 매입자료를 조회하시오 -- 2020월 2월 1일부터 <3월1일전

              Alias는 일자,상품코드,수량,금액

더보기

SELECT BUY_DATE AS 일자,
              BUY_PROD AS 상품코드,
              BUY_QTY AS 수량,
              BUY_COST*BUY_QTY AS 금액 -- 수량 * 단가
       FROM BUYPROD -- 매입테이블
       WHERE BUY_DATE>= TO_DATE('20200201') AND BUY_DATE <=LAST_DAY(TO_DATE('20200201'));

     --마지막날을 반환하여라

       
사용예) 키보드로 년도를 입력받아 해당년도가 윤년인지 평년인지를 판별하시오
        윤년 : 4의 배수이거나 100의 배수가 아닌해 또는 400의 배수인 년도
      

더보기

    ACCEPT P_YEAR PROMPT '년도 입력(YYYY) : ' -- 키보드로 입력받을수 있음
    DECLARE
        L_YEAR NUMBER:=TO_NUMBER('&P_YEAR');
        L_RES VARCHAR2(100);
    BEGIN
        IF (MOD(L_YEAR,4)=0 AND  MOD(L_YEAR,100)!=0) OR (MOD(L_YEAR,400)=0) THEN --MOD 나누기
            L_RES:=L_YEAR||'년은 윤년입니다';
        ELSE
            L_RES:=L_YEAR||'년은 평년입니다';
    END IF;
    
    DBMS_OUTPUT.PUT_LINE(L_RES);
    END;

 

- 기타연산자 : 복수행 비교연산자(IN, ANY, SOME, ALL, EXISTS), BETWEEN, LIKE 등 제공
               -- 복수개 데이터 >= 오른쪽 연산자 = 그 중의 어느하나가 존재할때
               -- 원래는 단일 데이터 비교가 원칙
               -- 범위를 나타낼때 논리곱 연산자 사용 ' 10< a <330' => a>10 AND a<330 --길어진다
               -- BETWEEN : ↑ 너무 길어서 범위를 나타낼때 사용
               -- LIKE : 문자열에만 쓰는 연산자. => 날짜나 숫자에는 쓰지말자

Oracle SQL - 기타연산자


- 기타연산자 : 복수행 비교연산자(IN, ANY, SOME, ALL, EXISTS), BETWEEN, LIKE 등 제공
 -- 복수개 데이터 >= 오른쪽 연산자 = 그 중의 어느하나가 존재할때
 -- 원래는 단일 데이터 비교가 원칙
 -- 범위를 나타낼때 논리곱 연산자 사용 ' 10< a <330' => a>10 AND a<330 --길어진다
 -- BETWEEN : ↑ 너무 길어서 범위를 나타낼때 사용
 -- LIKE : 문자열에만 쓰는 연산자. => 날짜나 숫자에는 쓰지말자
               
 - 다중 값의 비교연산을 수행(IN, ANY, SOME, ALL, EXISTS) 

    -- EXISTS는 뒤에 반드시 서브쿼리가와야해서 나중에 배움
 - 범위 설정(BETWEEN)
 - 패턴비교(LIKE)
 
1) IN 연산자 -- (or - in 서로 호환 가능)
  . 주어진 복수개의 값 중 어느 하나와 일치하면 전체 조건이 참의 결과를 반환
  . OR 연산자로 치환 가능
  . IN 연산자에는 '='(equal to)기능이 포함되어 있음.
  (사용형식)
  expr IN(값1,값2, ... 값n)
    - 'expr'의 값이 '값1,값2, ... 값n' 중 어느하나와 일치하면 TRUE 반환
    - 불연속적인 값의 비교나 불규칙적인 값의 비교에 유리

 


사용예) 사원테이블에서 30, 70, 80, 100부서에 속한 사원 정보를 조회하시오
        Alias는 사원번호,사원명,부서번호,직무코드이며 부서번호 순으로 출력
        
(OR 연산자 / IN 연산자)        

더보기

        SELECT 
                    EMPLOYEE_ID AS 사원번호,
                    EMP_NAME AS 사원명,
                    DEPARTMENT_ID AS 부서번호,
                    JOB_ID AS 직무코드        
             FROM HR.EMPLOYEES 
        WHERE DEPARTMENT_ID = 30 OR DEPARTMENT_ID = 70 OR

                      DEPARTMENT_ID = 80 OR DEPARTMENT_ID = 110
        ORDER BY 3;

 

        SELECT 
              EMPLOYEE_ID AS 사원번호,
              EMP_NAME AS 사원명,
              DEPARTMENT_ID AS 부서번호,
              JOB_ID AS 직무코드        
             FROM HR.EMPLOYEES 
        WHERE DEPARTMENT_ID IN(30,70,80,110)
        ORDER BY 3;

                      
        
        
사용예) 2020년 4월, 6월, 7월 매출집계를 조회하시오. Alias는 월,매출수량 합계,매출금액 합계
     

더보기


      SELECT SUBSTR(A.CART_NO,5,2)||'월' AS 월,
                     SUM(A.CART_QTY) AS "매출수량 합계",
                     TO_CHAR(SUM(A.CART_QTY * B.PROD_PRICE),'999,999,999') AS "매출금액 합계"
        FROM CART A, PROD B
      WHERE A.CART_PROD=B.PROD_ID

-- (조인조건)카트테이블의 PROD 상품코드가지고 상품테이블의 상품코드를 조회
      
            AND SUBSTR(A.CART_NO,1,6) IN('202004','202006','202007')

--CART_NO 장바구니 날짜 포함/년도4자리와 월 2자리
 GROUP BY SUBSTR(A.CART_NO,5,2) -- 같은 값끼리 모아라....
 ORDER BY 1;

-- 단가가 있는 테이블 PROD 상품테이블
-- 상품코드를 가지고 상품테이블의(부모테이블) => 판매단가 PROD_PRICE 찾아서 JOIN
-- SUBSTR문자열
-- 그룹화 GROUP BY /년도는 2020년으로 고정 => 월만 출력

 


사용예) 회원테이블에서 회원들의 보유 마일리지가 4000이상인 회원들의 

             2020년 구매현황을 조회하시오.    Alias 는 회원번호,회원명,구매금액 합계
         

더보기


        SELECT A.MEM_ID AS 회원번호,
                       A.MEM_NAME AS 회원명,              
                       SUM(B.CART_QTY * C.PROD_PRICE) AS "구매금액 합계"
            FROM MEMBER A, CART B, PROD C

           -- 회원은 MEMBER테이블, 구매수량은 CART테이블, 금액단가는 PROD 테이블          
            --   A, B, C = 테이블 별칭 //2이상의 테이블의 같은 컬럼명이 있을때 // FROM절에서만 가능함.
            
        WHERE   B.CART_MEMBER=A.MEM_ID
              AND B.CART_PROD=C.PROD_ID
              AND B.CART_NO LIKE '2020%'
              AND B.CART_MEMBER IN(SELECT MEM_ID
                                    FROM MEMBER
                                 WHERE MEM_MILEAGE >=4000)
     GROUP BY A.MEM_ID,A.MEM_NAME
     ORDER BY 1;

====================================================================

    SELECT A.MEM_ID AS 회원번호,
           A.MEM_NAME AS 회원명,
           SUM(B.CART_QTY*C.PROD_PRICE) AS 구매금액합계
    FROM MEMBER A, CART B, PROD C --=> 3개이므로 조인은 적어도 2개 이상
    -- A,B,C (테이블 별칭) : 두 개이상의 테이블에서 컬럼명이 같으면 꼭 써야 함
    -- FROM 절에서만 별칭 선언한다. FROM 테이블명 별칭(,테이블명 별칭,...)
    -- SELECT 절과 WHERE 절에서 참조해서 적을 수 잇다. A.MEM_ID
    WHERE B.CART_MEMBER=A.MEM_ID
       AND B.CART_PROD=C.PROD_ID
       AND B.CART_NO LIKE '2020%'
       AND B.CART_MEMBER IN(SELECT MEM_ID
                         FROM MEMBER
                         WHERE MEM_MILEAGE >= 4000)
    GROUP BY A.MEM_ID,A.MEM_NAME
    ORDER BY 1;

    -- 오류 주의 별칭에 "구매금액 합계" 띄어쓰기 조심하자
        



2) ANY(SOME) 연산자 --'='기능이 없다.
  . 주어진 값들 중 어느 하나와 ANY(SOME) 앞에 기술된 관계연산자의 조건을 만족하면 TRUE
  . IN연산자는 '='기능이 포함되어 있지만 ANY(SOME)은 연산자 앞에 관계연산자를 반드시 기술해야함
    (즉, IN은 =ANY, =SOME과 같다)
  . ANY와 SOME은 완전히 동일한 기능 제공
  
사용형식)
    expr 관계연산자 ANY|SOME (값1,값2,...,값n)

사용예) 회원테이블에서 직업이 '자영업'인 회원들이 보유한 제일적은 마일리지보다 

            많은 마일리지를 보유한 회원들을 조회하시오.  Alias는 회원번호,회원명,직업,마일리지
            

더보기


     SELECT  MEM_ID AS 회원번호,
                     MEM_NAME AS 회원명,
                     MEM_JOB AS 직업,
                     MEM_MILEAGE AS 마일리지
        FROM MEMBER
     WHERE MEM_MILEAGE >ANY(자영업회원들의 마일리지);
     
     SELECT  MEM_ID AS 회원번호,
                     MEM_NAME AS 회원명,
                     MEM_JOB AS 직업,
                     MEM_MILEAGE AS 마일리지
        FROM MEMBER
     WHERE MEM_MILEAGE >ANY(SELECT  MEM_MILEAGE -- SOME을 쓴것과 같다.
                                                             FROM MEMBER
                                                          WHERE MEM_JOB='자영업') --3700,5300,1500,4300 //1500보다
    ORDER BY 4; -- 1500보다 많은사람만 출력



3) ALL 연산자 (조건이 AND로 연결된 것으로 간주) -- 모두 다 만족이 되어야 참이다.
  . 주어진 값 모두와 ALL 앞에 기술된 관계연산자의 조건을 만족하면 TRUE를 반환
  . IN연산자는 '='기능이 포함되어 있지만 ALL 은 연산자 앞에 관계연산자를 반드시 기술해야함
  . ALL연산자는 =ALL을 사용할 수 없다(다가속성) -- 거주지가 대전이면서 대구이면서 서울인 사람은 없다.
    -- <,> 부등호 관계만 사용 가능.

사용형식)
 expr 관계연산자 ALL값(값1, 값2... 값n)

사용예) 회원테이블에서 직업이 '자영업'인 어느 회원들이 보유한 마일리지보다 많이 보유한 마일리지를 

            보유한 회원들을 조회하시오. Alias는 회원번호,회원명,직업,마일리지
          

더보기

     SELECT MEM_ID AS 회원번호,
                    MEM_NAME AS 회원명,
                    MEM_JOB AS 직업,
                    MEM_MILEAGE AS 마일리지
        FROM MEMBER
    WHERE MEM_MILEAGE !=ALL(SELECT MEM_MILEAGE -- 같지 않은 마일리지 출력
                                                            FROM MEMBER
                                                         WHERE MEM_JOB='자영업')
    ORDER BY 4;    


         
4) BETWEEN 연산자
  . 범위를 지정할 때 사용
  . 모든 타입의 데이터에 사용가능

사용형식)
  expr BETWEEN 값1 AND 값2
  . expr에 저장된 내용이 '값1'에서 '값2' 사이의 값이면 TRUE 반환
  . AND 연산자로 대치 가능
  
사용예) 상품테이블에서 분류코드가 'P200'번대에 속한 상품정보를 조회하시오
       Alias는 상품번호,상품명,분류코드,매입단가,매출단가

더보기

       SELECT PROD_ID AS 상품번호,
                      PROD_NAME AS 상품명,
                      PROD_LGU AS 분류코드,
                      PROD_COST AS 매입단가,
                      PROD_PRICE AS 매출단가
         FROM PROD
--    WHERE PROD_LGU>='P200' AND PROD_LGU<'P299';
      WHERE PROD_LGU BETWEEN 'P200' AND 'P299';   (BETWEEN  A   AND  B)

 

** 사원테이블에 퇴직일자(RETIRE_DATE)컬럼 날짜타입으로추가시키시오
    ALTER TABLE HR.EMPLOYEES ADD(RETIRE_DATE DATE);
    
** 사원테이블의 입사일자(HIRE_DATE)를 10년 후의 값으로 변환하시오
    UPDATE HR.EMPLOYEES 
           SET HIRE_DATE=ADD_MONTHS(HIRE_DATE,120);

-- 10년후=120개월/ ADD_MONTHS 주어진 날짜에 +개월수 더한값 반환
    COMMIT;
    
    SELECT EMP_NAME, EXTRACT(YEAR FROM SYSDATE)HIRE_DATE
        FROM HR.EMPLOYEES
        
사용예) 사원테이블에서 근속년수에 따른 보너스를 지급하려한다. 
        지급액과 보너스를 조회하시오. 
        보너스는 근속년수가 5년 미만인 사원은 기본급의 15%, 
                          5~10년인 사원은 25%
                          그 이상인 사원은 40% 지급한다.
        지급액 = 기본급 + 보너스
      

더보기


    SELECT EMPLOYEE_ID AS 사원번호,
                   EMP_NAME AS 사원명,
                   HIRE_DATE AS 입사일,
                   EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) AS 근속년수,

            -- 오늘 - 입사일 = 근속년수
                   SALARY AS 기본급,
        CASE WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) <5 THEN 
                   ROUND(SALARY * 0.15) 
                   WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) >=5 AND
                   EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) <=10 THEN
                   ROUND(SALARY * 0.25) 
         ELSE 
                   ROUND(SALARY * 0.40) 
          END  AS 보너스,          
        CASE WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) <5 THEN 
                   SALARY+ROUND(SALARY * 0.15) 
                   WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) >=5 AND
                   EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) <=10 THEN
                   SALARY+ROUND(SALARY * 0.25) 
        ELSE 
                   SALARY+ROUND(SALARY * 0.40) 
          END AS 지급액     

        FROM HR.EMPLOYEES; -- 전직원 조회여서 WHERE절 없음

 

---------------------------------------------------------------------------------------------------

SELECT EMPLOYEE_ID AS 사원번호,
               EMP_NAME AS 사원명,
               HIRE_DATE AS 입사일,
               EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) AS 근속년수, -- 오늘 - 입사일
               SALARY AS 기본급,
    CASE WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) <5 THEN 
                           ROUND(SALARY * 0.15) 
               WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) BETWEEN 5 AND 10 THEN
                     ROUND(SALARY * 0.25) 
                ELSE 
                     ROUND(SALARY * 0.40) 
           END AS 보너스,          
   CASE WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) <5 THEN 
                     SALARY+ROUND(SALARY * 0.15) 
              WHEN EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) BETWEEN 5 AND 10  THEN
                     SALARY+ROUND(SALARY * 0.25) 
                ELSE 
                     SALARY+ROUND(SALARY * 0.40) 
           END AS 지급액     

        FROM HR.EMPLOYEES;




사용예) 매입테이블에서 2020년 3월 제품별 매입집계를 조회하시오 

    -- 제품별 : 같은 제품 끼리 => 집계함수 GROUP BY
        상품코드,상품명,매입수량,매입금액
        

더보기

SELECT  A.BUY_PROD AS 상품코드,
                    B.PROD_NAME AS 상품명,
                    SUM(A.BUY_QTY) AS 매입수량,
                    SUM(A.BUY_QTY*B.PROD_COST) AS 매입금액
       FROM  BUYPROD A, PROD B
--      WHERE A.BUY_DATE >='20200301' AND A.BUY_DATE <='20200331'
    WHERE A.BUY_DATE BETWEEN TO_DATE('20200301') AND TO_DATE('20200331')
          AND A.BUY_PROD=B.PROD_ID
  GROUP BY A.BUY_PROD, B.PROD_NAME
  ORDER BY 1;



5) LIKE 연산자
  . 패턴을 비교하여 같은 문자열 패턴이면 TRUE을 반환
  . 패턴을 구성하는 문자(와일드 카드로) '&'와 '_'가 사용
  . '%'
    - '%'가 쓰인 위치 이후의 문자와 대응(공백도 대응)
    - ex) '김%' : '김'으로 시작하는 모든 문자와 대응
          '%김%' : 문자열중 '김'이라는 글자가 존재하면 참(true) 반환
          '%김' : '김'으로 끝나는 모든 문자열과 대응
  . '_'
    - '_'가 쓰인 위치 이후의 하나의 문자와 대응
    - ex) '김_' : '김'으로 시작하는 2글자 문자열과 대응
          '_김_' : 3글자 문자열중 중간 글자가 '김'인 문자열과 대응
          '_김' : '김'으로 끝나는 2글자 문자열과 대응
          
          
사용형식)
  expr LIKE '패턴문자열'
    . 문자열 연산자임(숫자,날짜 자료는 사용 자제)
    . 연산결과 많은 자료가 반환되므로 Query의 수행 효율성은 낮음

  
  
사용예) 회원테이블에서 대전에 거주하는 회원을 조회하시오
        Alias는 회원번호,회원명,주소,마일리지

더보기

SELECT MEM_ID AS 회원번호,
                       MEM_NAME AS 회원명,
                       MEM_ADD1||' '||MEM_ADD2 AS 주소,
                       MEM_MILEAGE AS 마일리지
           FROM MEMBER
        WHERE MEM_ADD1 LIKE '대전%';

 

사용예) 장바구니 테이블에서 2020년 4월 판매현황을 출력하시오
        Alias는 날짜,회원번호, 상품코드, 판매수량

더보기

        SELECT SUBSTR(CART_NO,1,8) AS 날짜,
                       CART_MEMBER AS 회원번호, 
                       CART_PROD AS 상품코드, 
                       CART_QTY AS 판매수량
           FROM CART
        WHERE CART_NO LIKE '202004%' -- 202004~로 시작하는 문자열 검색
   ORDER BY 1;

 

+ Recent posts