■ 시퀀스란?

  오라클에서 순서를 지정해주는 객체   **오라클에서만 사용 가능

 

[1] 시퀀스의 생성

CREATE SEQUENCE seq_테이블명_idx START WITH 1 INCREMENT BY 1;
-- 또는 
CREATE SEQUENCE seq_테이블명_idx;

 

[2] 데이터 추가 시 시퀀스 추가 - 시퀀스명.nextVal

INSERT INTO sungtb VALUES(seq_sungtb_idx.nextVal, '일길동', 90, 80, 70);

 

[3] 시퀀스의 삭제

DROP SEQUENCE seq_sungtb_idx

 

■ 인덱스란?

  데이터베이스에서 데이터를 빠르게 탐색하기 위해 붙인 색인(포인터)

 

인덱스를 사용해야 하는 경우 

- 데이터 양이 많고 검색이 수정보다 빈번한 경우

- 도메인의 값이 다양한 값을 가지는 경우 

 

인덱스를 사용할 때 주의할 점

- 인덱스를 사용하는 열에 NULL이 지나치게 많으면 효율이 떨어진다.

 

 

■ NVL함수를 통해 인덱스 형성하기

[문법]

NVL(MAX(idx),0)+1
--> (1) Max(idx)는 idx칼럼에서 가장 큰 수를 반환
--> (2) NVL(a , 0)  :  a라는 칼럼에 NULL이 없으면 (or a라는 데이터가 있으면) 해당 데이터 반환
                    -- 그렇지 않고 NULL만 있으면 0으로 데이터를 대체한다.
    --> 곧, idx에 데이터가 없으면 0을 넣고, 있으면 그 데이터에 +1을 하겠다.

SELECT NVL(MAX(idx), 0) + 1 FROM book;
--> book이라는 테이블에서 가장 큰 인덱스 값을 가져오고 +1을 한다.

 

[예시]

CREATE TABLE book
(
   idx   INT,
   name  CHAR(3 CHAR) NOT NULL,
   price INT
);

ALTER TABLE book 
  ADD CONSTRAINT pk_book_idx PRIMARY KEY(idx);
  
-- SAMPLE DATA 입력
INSERT INTO book VALUES((SELECT nvl(MAX(idx), 0) + 1 FROM book),'Java',20000);
INSERT INTO book VALUES((SELECT nvl(MAX(idx), 0) + 1 FROM book),'Oracle',30000);
INSERT INTO book VALUES((SELECT nvl(MAX(idx), 0) + 1 FROM book),'HTML',24000);
INSERT INTO book VALUES((SELECT nvl(MAX(idx), 0) + 1 FROM book),'JSP',22000);

 

 

 

[출처]

- 인덱스 참조

https://ltk3934.tistory.com/67

https://coding-factory.tistory.com/746

- 시퀀스 참조

https://coding-factory.tistory.com/420

https://kerpect.tistory.com/17

 DB모델링

- ERD란? Entity Relationship Diagram, 개체 관계도라 하며,

            개체들 간의 관계를 나타내는 다이어그램이다.

- DB 모델링에 대한 자세한 내용은 아래 포스팅 참조

https://mangkyu.tistory.com/27

 

[Database] 6. 데이터 모델링(Data Modeling)

[ 본 사진은 쉽게 배우는 오라클로 배우는 데이터베이스 개론과 실습 ppt에서 캡처했습니다. ] 이번 장에서는 데이터 모델링(Data Modeling), ER 모델(ER Model)에 대해 알아보겠습니다. 1. 데이터 모델링

mangkyu.tistory.com

- DB 모델링 툴 

- 윈도우용툴 : EXERD, ERWIN (erwin.com) *erwin이 가장 자주 쓰는 툴이라고 한다.
- 맥용툴 : 에이쿼리툴 https://zakkum.tistory.com/76

 

 정규화란?

  데이터 베이스의 불필요한 중복을 줄이고 설계를 더 탄탄하게 재구성하는 테크닉

>>

  제 1 정규화   도메인이 원자 값(하나의 값)을 갖도록 테이블을 분해하는 것
  제 2 정규화   제 1정규화를 마친 테이블에서 완전함수 종속*을 만족하도록 테이블을 분해
  * 기본키의 부분 집합이 결정자가 되어서는 안된다. 

  EX. 테이블 1 ) 기본키 : 학생번호/강좌이름, 데이터 : 강의실, 성적
     * 성적은 학생번호/강좌이름에 종속적이다.
     * 강의실은 강좌이름에 종속적이다.
     
     ---> 테이블 1, 2로 분해
            테이블 1 ) 기본키 : 학생번호, 데이터 : 강좌이름, 성적
            테이블 2 ) 기본키 : 강좌이름, 데이터 : 강의실
  제 3 정규화   제 2정규화를 마친 테이블에 대해 이행적 함수 종속*을 없애도록 테이블을 분해
  * A, B, C 데이터가 있을 때, A -> B -> C 관계만 가능하도록 해야한다.
  * A -> C (X)

  EX. 테이블 1 ) 기본키 : 학생번호, 데이터 : 강좌이름, 수강료
     * 강좌이름은 학생번호에 종속적이다.
     * 수강료는 강좌이름에 종속적이다.

     ---> 테이블 1,2로 분해
     테이블 1 ) 기본키 : 학생번호, 데이터 : 강좌이름
     테이블 2 ) 기본키 : 강좌이름, 데이터 : 수강료
     * 학생번호 -> 강좌이름 -> 수강료
     >> 학생번호로 수강료를 알 수 있으면 안 된다.

 

* 완전 함수 종속 : 기본키가 여러개일 때, 모든 기본키에 종속적이어야 한다는 것

* 이행적 함수 종속 : 순차적인 이행에 따른 종속 관계 

 

 정규화의 장단점 - 가장 큰 이점 : 이상현상의 제거

장점 단점
[1] 데이터베이스 변경 시 이상 현상 방지
[2] 데이터베이스 구조 확장 시 재 디자인 최소화
[3] 사용자에게 데이터 모델을 더욱 의미있게 제공
테이블의 분해로 인해 테이블간 연산(JOIN)이 많아진다.
이로인해 질의에 대한 응답시간이 늦어질 수도 있다.
(성능저하의 가능성)

 

■ 역정규화를 하는 이유

  정규화를 거치면 릴레이션 간의 연산(JOIN 연산)이 많아지는데, 이로인해 성능이 저하될 우려가 있습니다.
  역정규화를 하는 가장 큰 이유는 성능 문제가 있는(읽기작업이 많이 필요한) DB의 전반적인 성능을 향상시키기 위함입니다.

 

이상현상(Anomaly)의 종류

 - 이상현상이란? 테이블을 잘못 설계하여 데이터를 삽입, 삭제, 수정할 때 생기는 논리적 오류

  삽입 이상    자료를 삽입할 때 특정 속성에 해당하는 값이 없어 NULL을 입력해야 하는 현상
  갱신 이상    중복된 데이터 중 일부만 수정되어 데이터 모순이 일어나는 현상
  삭제 이상    어떤 정보를 삭제하면, 의도하지 않은 다른 정보까지 삭제되어버리는 현상

 

 

[참조]

- 정규화 참조

https://dev-coco.tistory.com/62
https://mr-dan.tistory.com/10

https://programming119.tistory.com/225

 

 

 

 

'Language > SQL' 카테고리의 다른 글

[DATABASE] JOIN  (0) 2022.04.21
[DATABASE] SEQUENCE, INDEX  (0) 2022.04.21
[DATABASE] 뷰 (VIEW), 인라인 뷰  (0) 2022.04.19
[DATABASE] DECODE, CASE~END 문  (0) 2022.04.18
[DATABASE] 정렬(ORDER NY) 및 그룹 통계(GROUP BY)  (0) 2022.04.18

■ 뷰(VIEW)의 정의

- 뷰는 가상 객체로, 하나 이상의 테이블 또는 뷰의 데이터를 볼 수 있게 한다. 

- 실제로 테이블은 아니지만 테이블처럼 사용 가능

- 다른 뷰를 참조해 새로운 뷰를 생성할 수 있다.

 

■ 뷰(VIEW)의 사용 목적

- [1] 편리성 : 복잡한 명령/수식 등을 간결하게 사용 가능

- [2] 보안성 : 중요 데이터를 외부로 제한적으로 제공

  * DBO의 원천데이터를 선별적으로 가공하여 사용자에게 (조회)권한 부여

 

■ 뷰(VIEW)의 실제 형태

- .bat 파일과 같이 실제로는 Select ~ from SQL문이 들어가있는 형태

 

■ 뷰(VIEW)를 생성할 수 있는 권한 부여 *최고 권한자만 권한을 부여할 수 있다.

grant create view to 계정

 

■ 뷰(VIEW)의 생성 및 수정

더보기

>> 아래에서 예제를 사용하기 위한 테이블 생성 코드

CREATE TABLE MEMBER
(
   EIN     NUMBER(5)      NOT NULL, --EMPLOYMENT ID NUMBER
   NAME    CHAR(5 CHAR)   NOT NULL,
   ADDR    VARCHAR2(150)  NOT NULL, 
   SSN     CHAR(15 CHAR) NOT NULL, -- SOCIAL SECURITY NUMBER
   HIREDAY DATE,
   
   CONSTRAINT UNIQUE_MEMBER_EIN UNIQUE(EIN)
);

ALTER TABLE MEMBER
  ADD CONSTRAINT PK_MEMBER_EIN PRIMARY KEY(EIN);
  
INSERT INTO MEMBER VALUES(1, '김길동', '경기도 김포시 장기동', '951221-1354888','1998-07-22');
INSERT INTO MEMBER VALUES(2, '나길동', '서울시 관악구 테헤란로', '931221-2354888','1998-07-22');
INSERT INTO MEMBER VALUES(3, '다길동', '서울시 관악구 문성로', '950821-1354888','1998-07-22');
INSERT INTO MEMBER VALUES(4, '라길동', '천안시 동남구 대흥동', '921221-1354888','1998-07-22');
INSERT INTO MEMBER VALUES(5, '마길동', '천안시 동남구 대흥동', '911221-2354888','1998-07-22');
INSERT INTO MEMBER VALUES(6, '바길동', '삼척시 원덕읍 호산리', '950321-1354888','1998-07-22');
INSERT INTO MEMBER VALUES(7, '사길동', '삼척시 원덕읍 호산리', '650721-2354888','1998-07-22');
INSERT INTO MEMBER VALUES(8, '아길동', '삼척시 원덕읍 호산리', '630121-1354888','1998-07-22');
INSERT INTO MEMBER VALUES(9, '자길동', '서울시 관악구 문성로', '571221-2354888','1998-07-22');
INSERT INTO MEMBER VALUES(10, '차길동', '경기도 김포시 장기동', '881221-1354888','1998-07-22');

SELECT * FROM MEMBER
CREATE OR REPLACE 뷰이름
AS
  /* SQL 문장 */

[예제1 _ 뷰 만들기]

-- 맴버 테이블에서 입사연도/입사월/입사일을 구하는 뷰

CREATE OR REPLACE VIEW MEMBER_HIREDATES
AS
	SELECT
	  MB.*,
	  TO_NUMBER(TO_CHAR(HIREDAY, 'YYYY')) AS HIRE_YEAR,
	  TO_NUMBER(TO_CHAR(HIREDAY, 'MM')) AS HIRE_MONTH,
	  TO_NUMBER(TO_CHAR(HIREDAY, 'DD')) AS HIRE_DAY
	FROM MEMBER MB
	WHERE SAHIRE IS NOT NULL
    
-- 생성한 뷰를 통해 입사연도별 인원수 구하기
SELECT
  HIRE_YEAR,
  COUNT(*) 인원수
FROM MEMBER_HIREDATES
GROUP BY HIRE_YEAR

[예제2_ 뷰의 보안성을 이해하는 예제]

-- 주민 등록번호 마스킹 처리한 MEMBER테이블을 뷰로 저장
CREATE OR REPLACE VIEW SSN_MASKED_VIEW
AS
	SELECT
	  EIN, NAME, ADDR, 
	  (
	    SUBSTR(SSN, 1, 7)
	    ||
	    '*******'
	  )AS SSN,
	  HIREDAY
	FROM MEMBER

SELECT * FROM SSN_MASKED_VIEW;

>> 결과

 

■ 인라인 뷰 사용하기

- 테이블/뷰에서 모든 데이터 + 별도의 함수식에 의한 데이터를 불러올 때나,

- 코드를 간소화하고 싶을 때에 인라인 뷰를 사용한다.

SELECT
  임시별칭.*,
  CASE문 또는 수식
FROM (SELECT * FROM 테이블/뷰) 임시별칭

[예제]

-- 맴버 테이블에서 계절만 따로 뽑아오기

SELECT
  MB.*,
  CASE FLOOR(TO_NUMBER(TO_CHAR(HIREDAY,'DD')) / 3) 
     WHEN 1 THEN '봄'
     WHEN 2 THEN '여름'
     WHEN 3 THEN '가을'
     ELSE '겨울'
  END AS 생일
FROM (SELECT * FROM MEMBER) MB   -- MB라는 뷰가 임시로 하나 생성된 것과 같은 원리(실제로 생성x)

 

 

■ 뷰(VIEW)의 사용 권한 부여

- DBO(실제 테이블 소유 계정)는 뷰를 통해 DBA(테이블을 사용하는 계정)에게 일부의 데이터만 선택하거나 보안화하여 제공한다.

- 사용 권한을 부여하는 코드는 아래와 같다.

GRANT SELECT ON 뷰이름 TO 계정명

 

[예제]

-- [새로운 계정에 조회 권한만 부여할 때]
-- SQLPLUS에서 아래와 같이 작성

-- 1. 최고 권한자로 로그인
SQLPLUS SYSTEM/ORACLE;

-- 2. 새로운 계정 생성
CREATE USER MYTEST1 IDENTIFIED BY MYTEST1;

-- 3. 새로운 계정에 연결 권한 부여
GRANT CONNECT TO MYTEST1;

-- 4. 사용할 뷰를 가진 DBO계정으로 연결
CONN TEST1/TEST1;

-- 5. 새로운 계정에 뷰 권한 부여
GRANT SELECT ON SSN_MASKED_VIEW TO MEMBER_TEST;

-- 6. 새로운 계정으로 연결
CONN MYTEST1/MYTEST1;

-- 7. 뷰 조회
SELECT * FROM SSN_MASKED_VIEW;

 

 

[출처]

- https://coding-factory.tistory.com/417

- 국비지원 수업 내용 참조

■ DECODE 문

형식 : DECODE(필드(연산식), 비교값1, 결과값1,
                            비교값2, 결과값2,
                            비교값3, 결과값3,
                            기본값)
CREATE TABLE MEMBER
(
   IDX NUMBER(38),
   DEPTNO NUMBER(10),
   NAME CHAR(4 CHAR),
   GENDER CHAR(3 CHAR)
);

/* INSERT 생략 */

SELECT
   IDX, DEPTNO, NAME,
   DECODE(DEPTNO, 10, '총무부',
                  20, '영업부',
                  30, '전산실',
                  40, '관리부',
                  '경리부') AS DEPTNAME;

 

■ CASE ~ END 문

CASE ~ END

-- 형식 1 : 하나의 조건에 대한 값을 비교하여 결과를 얻는다.
    CASE 필드(연산식)
      WHEN 비교값1 THEN 결과값1
      WHEN 비교값2 THEN 결과값2
      WHEN 비교값3 THEN 결과값3
      ELSE 기본값
    END
    
-- 형식2 : 각각의 조건에 대한 별개의 결과를 얻는다.
   CASE 
     WHEN 조건1 THEN 결과값1
     WHEN 조건2 THEN 결과값2
     ELSE 기본값
   END
-- 형식 1 : 하나의 조건에 대한 값을 비교하여 결과를 얻는다.
        CASE 필드(연산식)
          WHEN 비교값1 THEN 결과값1
          WHEN 비교값2 THEN 결과값2
          WHEN 비교값3 THEN 결과값3
          ELSE 기본값
        END
        
  --CASE ~END문 이용해서 부서명 출력
        
  SELECT 
     SABUN,
     SANAME,
     DEPTNO,
     CASE DEPTNO
       WHEN 10 THEN '총무부'
       WHEN 20 THEN '영업부'
       WHEN 30 THEN '전산실'
       WHEN 40 THEN '관리부'
       ELSE '경리부'
     END AS DNAME
  FROM SAWON
 
 ---형식2 : 각각의 조건에 대한 별개의 결과를 얻는다.
       CASE 
         WHEN 조건1 THEN 결과값1
         WHEN 조건2 THEN 결과값2
         ELSE 기본값
       END

  --CASE ~END 문 이용해서 성별 추출
  SELECT
    GOBUN,
    GONAME,
    GOJUMIN,
    CASE
      WHEN SUBSTR(GOJUMIN,8,1) IN ('1', '3', '5', '7', '9') THEN '남자'
      WHEN SUBSTR(GOJUMIN,8,1) IN ('2', '4', '6', '8', '0') THEN '여자'
    END AS GENDER
  FROM GOGEK;
  
  SELECT
    GOBUN,
    GONAME,
    GOJUMIN,
    CASE
      WHEN TO_NUMBER(SUBSTR(GOJUMIN,8,1)) IN (1,3,5,7,9) THEN '남자'
      WHEN TO_NUMBER(SUBSTR(GOJUMIN,8,1)) IN (2,4,6,8,0) THEN '여자'
    END AS GENDER
  FROM GOGEK;
  
  
 -- Q1. 사원테이블에서 사번, 이름, 입사시즌(입사계절)을 추출
  SELECT
    SABUN AS 사번,
    SANAME AS 이름,
    CASE FLOOR(TO_NUMBER(TO_CHAR(SAHIRE,'MM'))/3)
      WHEN 1 THEN '봄'
      WHEN 2 THEN '여름'
      WHEN 3 THEN '가을'
      ELSE '겨울'
    END AS 입사시즌
  FROM SAWON
  
 -- Q2. 고객테이블에서 고객번호, 고객이름, 고객의 출생 계절 추출
  
  -- [형식1]
  SELECT
    GOBUN,
    GONAME,
    CASE FLOOR(TO_NUMBER(SUBSTR(GOJUMIN,3,2))/3)
      WHEN 1 THEN '봄'
      WHEN 2 THEN '여름'
      WHEN 3 THEN '가을'
      ELSE '겨울'
    END AS 출생계절
  FROM GOGEK;
  
  -- [형식2]
  SELECT
    GOBUN,
    GONAME,
    GOJUMIN,
    CASE 
      WHEN SUBSTR(GOJUMIN,3,2) IN ('03','04','05') THEN '봄'
      WHEN SUBSTR(GOJUMIN,3,2) IN ('06','07','08') THEN '여름'
      WHEN SUBSTR(GOJUMIN,3,2) IN ('09','10','11') THEN '가을'
      ELSE '겨울'
    END 출생계절
  FROM GOGEK

■ 정렬 (ORDER BY)

ORDER BY 필드 [asc | desc]  필드를 기준으로 정렬
ORDER BY 필드1 [asc | desc], 필드2 [asc | desc] 필드1을 기준으로 1차 정렬 후, 필드2를 기준으로 2차 정렬

* ASC = ASCENDING (오름차순), DESC = DESCENDING (내림차순)

 

■ 그룹 통계 (GROUP BY)

GROUP BY 필드 필드의 분류를 기준으로 그룹핑

* SELECT ~ FROM 사이에 들어올 수 있는 항목, GROUP BY 컬럼, 통계함수(COUTN,SUM,AGV,MIN,MAX..)

 

[예제1 _ 부서별 인원수, 급여 합계를 구하는 쿼리]

SELECT 
  DEPTNO 부서번호,
  AVG(SALARY) 급여평균,
  MAX(SALARY) 최고급여,
  MIN(SALARY) 최소급여
FROM MEMBER
GROUP BY DEPTNO
ORDER BY DEPTNO

 

[예제2 _ 연봉 3000이상인 부서간 성별 인원수, 평균급여]

SELECT
   DEPTNO 부서번호,
   GENDER 성별,
   COUNT(*) 인원수,
   AVG(SALARY) 급여평균
FROM MEMBER
WHERE SALARY >= 3000
GROUP BY DEPTNO, GENDER
ORDER BY DEPTNO, GENDER;

 

'Language > SQL' 카테고리의 다른 글

[DATABASE] 뷰 (VIEW), 인라인 뷰  (0) 2022.04.19
[DATABASE] DECODE, CASE~END 문  (0) 2022.04.18
[DATABASE] SELECT쿼리 진행 순서, 서브쿼리  (0) 2022.04.17
[DATABASE] 중복 값 제거 _ DISTINCT  (0) 2022.04.16
[DATABASE] 함수  (0) 2022.04.15

[자료구조 알고리즘] Stack 구현하기 in Java - YouTube

 

[ 스택의 활용 예 : 출처 자바의 정석 ]

수식 계산, 수식괄호검사, 워드프로세서의 undo/redo, 웹브라우저의 뒤로/앞으로

 

★ 문제 : 10828번: 스택 (acmicpc.net)

 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

★ 스택 단계 (acmicpc.net)

 

스택 단계

주어진 문자열이 올바른 괄호열인지 판단하는 문제

www.acmicpc.net

 

■ 스택을 생성해보는 예제 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class _00_스택 {
	public static void main(String[] args) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer token;
		
		//스택 인스턴스 생성
		Stack stack = new Stack();
		
		//첫번째줄 입력값(명령의 수) 
		int N = Integer.parseInt(reader.readLine()); 
		
		//명령 문자열 한 줄
		String input;
		//명령어
		String order;
		
		while (N > 0) {
			input = reader.readLine();
			token = new StringTokenizer(input);
			order = token.nextToken();
			
			//명령어에 따라 스택 메소드 실행
			if (order.equals("push")) {
				int item = Integer.parseInt(token.nextToken());
				stack.push(item);
			} else if (order.equals("pop")) {
				stack.pop();
			} else if (order.equals("size")) {
				stack.size();
			} else if (order.equals("empty")) {
				stack.empty();
			} else if (order.equals("top")) {
				stack.top();
			}
			
			N--;
		}
	}
}

class Stack {
	//노드 내부 클래스 정의
	class Node {
		private int data;
		private Node next;
	}
	
	//가장 위에 있는 노드
	private Node top;
	
	//push메소드 : 노드 삽입
	public void push(int item) {
		Node t = new Node();
		t.data = item;
		t.next = top;
		top = t;
	
	//pop메소드 : 노드 빼기 (뺄 때, 데이터값 읽기)
	public void pop() {
	    if (top == null) {
	    	System.out.println("-1");
	    }else {
	    	Node tmp = top;
	    	top = top.next;
	    	System.out.println(tmp.data);
	    }
	}//pop()
	
	//size메소드 : 노드의 갯수 반환
	public void size() {
		int count = 1;
		Node tmp = top;
		
		if (top == null) {
			System.out.println(0);
		} else {
			while(tmp.next != null) {
				tmp = tmp.next;
				count++;
			}
			System.out.println(count);
		}
	}//size()
	
	//empty메소드(isEmpty) : 노드가 있는지 여부 확인
	public void empty() {
		if (top == null) {
			System.out.println(1);
		} else {
			System.out.println(0);
		}
	}//empty()
	
	//top메소드(peek) : top노드 데이터 읽기
	public void top() {
		if (top == null) {
			System.out.println("-1");
		} else {
			System.out.println(top.data);
		}
	}//top()
	
}

 

 

'Computer Science > Algorithm' 카테고리의 다른 글

[정렬] 퀵 정렬(Quick Sort)  (1) 2022.05.10
[자료구조] 큐(Queue)  (0) 2022.04.28
[검색] 선형탐색과 이진탐색  (0) 2022.04.12
[자바의 정석] 스택과 큐  (0) 2022.03.30
[자바의 정석] ArrayList/LinkedList  (0) 2022.03.29

■ SELECT 쿼리 진행 순서

  FROM, JOIN > WHERE, GROUP BY, HAVING > SELECT > ORDER BY > DISTINCT > LIMIT

 

▼ 자세한 진행 순서 [더보기]

더보기

1. FROM과 JOIN

- JOIN이 먼저 실행되어 데이터가 SET으로 모아지게 된다. 서브쿼리도 함께 포함되어 임시 테이블을 만들 수 있게 도와준다.

2. WHERE

- 데이터셋을 형성하게 되면 WHERE의 조건이 개별 행에 적용된다. WHERE절의 제약 조건은 FROM절로 가져온 테이블에 적용될 수 있다.

3. GROUP BY

- WHERE의 조건 적용 후 나머지 행은 GROUP BY절에 지정된 열의 공통 값을 기준으로 그룹화된다. 쿼리에 집계 기능이 있는 경우에만 이 기능을 사용해야 한다.

4. HAVING

- GROUP BY절이 쿼리에 있을 경우 HAVING 절의 제약조건이 그룹화된 행에 적용된다.

5. SELECT

- SELECT에 표현된 식이 마지막으로 적용된다.

6. DISTINCT

- 표현된 행에서 중복된 행은 삭제

7.ORDER BY

- 지정된 데이터를 기준으로 오름차순, 내림차순 지정

8. LIMIT

- LIMIT에서 벗어나는 행들은 제외되어 출력된다.



출처: https://dev-coco.tistory.com/158 [슬기로운 개발생활😃]

 

 

■ 서브 쿼리

단일 행(Sing-Row) 서브쿼리 SELECT 문장으로 부터 오직 하나의 행 만을 검색하는 질의
다중 행(Multiple-Row) 서브쿼리 SELECT 문장으로부터 하나 이상의 행을 검색하는 질의
다중 열(Multiple-Column) 서브쿼리 SELECT 문장으로부터 하나 이상의 컬럼을 검색하는 질의
FROM절상의 서브쿼리(INLINE VIEW) FROM절상에 오는 서브쿼리로 VIEW처럼 작용
상관관계 서브 쿼리 바깥쪽 쿼리의 컬럼 중의 하나가 안쪽 서브쿼리의 조건에 이용되는 처리 방식

 

[단일행 서브쿼리 예시]

-- Q1. 사원 테이블에서 이미자와 동일한 계절에 입사한 직원 추출
SELECT * FROM SAWON 
  WHERE TRUNC(TO_NUMBER(TO_CHAR(sahire,'MM')) / 3, 0) = (
                                                            SELECT
                                                               TRUNC(TO_NUMBER(TO_CHAR(sahire,'MM')) / 3, 0)
                                                               FROM SAWON
                                                               WHERE SANAME = '이미자'
                                                         );


-- Q2. 사원 테이블에서 총 급여 평균 보다 더 급여를 많이 받는 직원 추출
SELECT * FROM SAWON
  WHERE SAPAY > (SELECT AVG(SAPAY) FROM SAWON);


-- Q3. 사원 테이블에서 최초 입사한 직원을 추출
SELECT * FROM SAWON
 WHERE SAHIRE = (SELECT MIN(SAHIRE) FROM SAWON)


-- Q4. 사원 테이블에서 가장 최근 입사한 직원을 추출 
SELECT * FROM SAWON
 WHERE SAHIRE = (SELECT MAX(SAHIRE) FROM SAWON)

-- Q5. 사원 테이블에서 일자를 기준으로 최초입사자, 최근입사자를 모두 추출
SELECT * FROM SAWON
  WHERE SAHIRE = (SELECT MIN(SAHIRE) FROM SAWON)
        or
        SAHIRE = (SELECT MAX(SAHIRE) FROM SAWON);

 

[다중행 연산자]

IN 연산자 하나의 컬럼이 여러개의 '=' 조건을 가지는 경우 사용. 포함된다는 의미
ANY 연산자 Subquery의 여러 결과값 중 어느 하나의 값만 만족이 되면 행을 반환
ALL 연산자 Subquery의 여러 결과값 중 모든 결과 값을 만족해야 행을 반환
EXISTS 연산자  Subquery 데이터가 존재하는가를 체크해 존재 여부(TRUE,FALSE)를 결과로 반환
-- IN은 같냐를 바꾼 것
SELECT * FROM sawon
 WHERE deptno IN (SELECT deptno FROM sawon WHERE saname = '최불암')
   
-- ANY를 붙이면 다중행 있을 때,
-- 3000이상 받는지 OR 3500이상 받는지
-- (이미자가 둘 이상 있을 떄) 사원 테이블에서 이미자와 같거나 더 큰 급여를 받는 직원 추출
SELECT * FROM sawon
 WHERE sajob >= ANY (SELECT sajob FROM sawon WHERE saname = '이미자')

-- ALL를 붙이면 다중행 있을 때.
-- 3000이상이면서 35000이상이어야한다. 
-- (이미자가 둘 이상 있을 떄) 사원 테이블에서 이미자와 같거나 더 큰 급여를 받는 직원 추출
SELECT * FROM sawon
 WHERE sajob >= ALL (SELECT sajob FROM sawon WHERE saname = '이미자')

 

[상관쿼리]

- 주 쿼리의 정보를 서브쿼리가 이용해서 추출된 결과를 주쿼리를 선택하는데 이용한다.

-- 사원 테이블에서 각 부서별 최고 급여자를 추출한다고 했을 때

[방법1] 조건을 하나씩 달아준다.
-- >> 아래 코드의 경우, 부서가 증가하거나, 부서번호가 변경되면 일일히 수정해야한다.
SELECT * FROM SAWON
  WHERE SAPAY = (SELECT MAX(SAPAY) FROM SAWON WHERE DEPTNO = 10) and DEPTNO = 10
        OR
        SAPAY = (SELECT MAX(SAPAY) FROM SAWON WHERE DEPTNO = 20) and DEPTNO = 20
        OR
        SAPAY = (SELECT MAX(SAPAY) FROM SAWON WHERE DEPTNO = 30) and DEPTNO = 30
        OR
        SAPAY = (SELECT MAX(SAPAY) FROM SAWON WHERE DEPTNO = 40) and DEPTNO = 40
  ORDER BY DEPTNO ASC;  -- 부서번호별 오름차순

[방법2] 상관쿼리르 사용한다.
-- 위의 SQL문의 문제점(코드가 너무 길다) 해결 
-- >> 상관쿼리 : 주쿼리의 정보를 서브쿼리가 이용해서 추출된 결과를 주쿼리를 선택하는데 이용한다. 
SELECT * FROM SAWON S1
  WHERE SAPAY = (SELECT MAX(SAPAY) FROM SAWON WHERE DEPTNO = S1.DEPTNO)
  ORDER BY S1.DEPTNO ASC;

 

 

[출처]

- https://dev-coco.tistory.com/158

- https://myjamong.tistory.com/172

- http://www.gurubee.net/

- 국비지원과정 수업 참조

■ 중복값 제거 DISTINCT

- 하나의 컬럼의 데이터를 뽑아낼 때, 중복값을 제거하고 출력

SELECT DISTINCT AGE FROM MEMBER;

 

■ 변환 함수

https://webstudynote.tistory.com/60

https://webstudynote.tistory.com/60

함수 내용
TO_CHAR(number)
TO_CHAR(number, format)
TO_CHAR(date, FORMAT)
DATE형, NUMBER형을 문자 타입으로 변환
TO_DATE(char, format) CHAR, VARCHAR2형을 DATE 타입으로 변환
TO_ NUMBER(char)  CHAR, VARCHAR2의 데이터 타입을 숫자형식으로 변환
더보기

출처 : http://www.gurubee.net/lecture/1027
- 주요 숫자 포맷과 날짜 포맷을 여기서 확인할 수 있다.

■ 문자열 함수

함수 내용
CONCAT('www.' , 'naver.com') 문자열 결합 연산자 || 와 동일한 기능을 하는 함수
INITCAP(문자) 첫글자를 대문자로, 나머지는 소문자로 변경
LOWER(문자) 모든 문자를 소문자로 변경
UPPER(문자) 모든 문자를 대문자로 변경
SUBSTR(문자,시작인덱스,갯수) 'HELLO'의 첫번째문자에서 세개를 뺀다
LENGTH(문자) 문자열의 길이를 반환한다.
REPLACE(전체 문자,바꿀 영역, 대체 문자) 문자의 일부를 다른 문자로 대체
INSTR(전체 문자, 찾을 문자) 전체 문자에 찾을 문자가 없으면 0, 있으면 위치를 반환
TRIM(전체 문자) 공백 제거

 

■ 숫자 함수

함수 내용
ABS(양수 또는 음수) 양수 또는 음수의 절대값 반환
CEIL(n) 올림값을 반환
FLOOR(n) 버림값을 반환
MOD(m, n) m을 n으로 나눈 나머지를 반환
ROUND(n, [m]) n값의 반올림 반환. m은 소수점 아래 자릿수
TRUNC(n, m) n값을 절삭하고 반환. m은 소숫점 아래 자릿수

 

■ 날짜 함수

함수 내용
SYSDATE 시스템 현재 일자 *최소단위 = 1초
SYSTIMESTAMP 시스템 현재 일자(시분초) *최소단위 = 10억분의 1초
ADD_MONTHS(a, b) a의 날짜에 b의 달을 더한 값을 반환
MONTHS_BETWEEN(a1, a2) a1과 a2 사이의 달의 수를 NUMBER형 타입으로 반환
LAST_DAY(d) 달의 마지막 날의 날짜를 반환
NEXT_DAY(d, c1) 1(일) ~ 7(토)을 기준으로 돌아오는 명시된 요일의 일자를 반환한다.
ROUND(d[,F]) F에 지정된 단위로 반올림 *생략시 '일'을 기준으로
TRUNC(d[,F]) F에 지정된 단위로 절삭

 

[SYSDATE를 통해 현재시간, MONTH, HOUR, MINUTE 전 시간 구하기]

-- SYSDTE 예제
SELECT TO_CHAR(SYSDATE,'RRRR-MM-DD HH24:MI:SS') "지금시간"
  FROM DUAL ;
 
SELECT TO_CHAR(SYSDATE-1,'RRRR-MM-DD HH24:MI:SS') "하루전지금시간"
  FROM DUAL ;
 
SELECT TO_CHAR(SYSDATE-1/24,'RRRR-MM-DD HH24:MI:SS') "1시간전시간"
  FROM DUAL ;
 
SELECT TO_CHAR(SYSDATE-1/24/60,'RRRR-MM-DD HH24:MI:SS') "1분전시간"
  FROM DUAL ;
 
SELECT TO_CHAR(SYSDATE-1/24/60/10,'RRRR-MM-DD HH24:MI:SS') "6초전시간"
  FROM DUAL ;
 
SELECT TO_CHAR(SYSDATE-(5/24 + 30/24/60 + 10/24/60/60),'RRRR-MM-DD HH24:MI:SS') "5시간 30분 10초전"
  FROM DUAL ;

 

[SYSTIMESTAMP를 통해 현재시간, MONTH, HOUR, MINUTE 전 시간 구하기]

-- SYSTIMESTAMP
-- SYSTIMESTAMP 함수를 사용하면 현재 일자와 시간(시스템기준)을 얻을 수 있다.
-- SYSTIMESTAMP 예제
SELECT TO_CHAR(SYSTIMESTAMP,'RRRR-MM-DD HH24:MI:SS.FF3')  
  FROM DUAL ;
 
SELECT TO_CHAR(SYSTIMESTAMP,'RRRR-MM-DD HH24:MI:SS.FF9')  
  FROM DUAL ;
 
SELECT TO_CHAR(SYSTIMESTAMP -1/24,'RRRR-MM-DD HH24:MI:SS') "1시간전시간"
  FROM DUAL ;
 
SELECT TO_CHAR(SYSTIMESTAMP -1/24/60,'RRRR-MM-DD HH24:MI:SS') "1분전시간"
  FROM DUAL ;

 

[내가 살아온 개월 수, 일수]

--Q1. 내가 살아온 월 수 or 일 수
SELECT MONTHS_BETWEEN(TO_DATE(SYSDATE, 'RRRR-MM-DD'),
                      TO_DATE('2000-01-01', 'RRRR-MM-DD')) AS "내가 살아온 월 수"
  FROM DUAL;
  
SELECT TRUNC(MONTHS_BETWEEN(TO_DATE(SYSDATE, 'RRRR-MM-DD'),
                      TO_DATE('2000-01-01', 'RRRR-MM-DD')),1) AS "내가 살아온 월 수"
  FROM DUAL;

SELECT TO_DATE(SYSDATE, 'RRRR-MM-DD') -
       TO_DATE('2000-01-01', 'RRRR-MM-DD') as "내가 살아온 날 수"
  FROM DUAL;

 

■ 집계 함수

함수 내용
AVG()           (평균) 평균 값을 반환
COUNT()       (개수) 검색된 행의 수
MAX()          (최대값) 컬럼값 중에서 최대값을 반환
MIN()           (최소값) 컬럼값 중에서 최소값을 반환
SUM()           (합계)  검색된 컬럼의 합을 반환
STDDEV() 표준변차 반환

 

■ NULL과 관련된 함수

함수 내용
NVL(필드, 대체값) NULL이면 대체값 대입 (NULL이 아니면 그대로 사용)
NVL2(필드, 참값 ,거짓값) NULL이 아니면 참값, NULL이면 거짓값
CREATE TABLE MEMBER
(
   DEPTNO NUMBER(5),
   NAME CHAR(3 CHAR),
   RECDATE DATE,
   SECTOR VARCHAR2(100)
)

SELECT  
    NAME, RECDATE, 
    NVL(SECTOR, '미지정') AS SECTOR, 
    NVL2(SECTOR, '지정 완료', '미지정') AS SECTOR
FROM MEMBER

 

 

[출처]

- http://www.gurubee.net/

- 뉴렉처 강의

- 국비 수업 과정 참조

 

+ Recent posts