반응형

CNN (Convolutional Neural Network)

  • CNN은 최소한의 전처리(preprocess)를 사용하도록 설계된 다계층 퍼셉트론의 한 종류이다.
  • CNN은 하나 또는 여러개의 합성곱 계층과 그 위에 올려진 일반적인 인공 신경망 계층들로 이루어져 있으며, 가중치와 통합 계층(pooling layer)들을 추가로 활용한다.
  • DNN에서는 Dense Layer를 사용한다. → Dense Layer는 Wx+b이라서 Linear와 Rogistic 회귀가 합쳐진 느낌
  • CNN에서는 Convolution이라는 연산을 활용함
퍼셉트론 관련 포스팅 [AI] 딥러닝의 개요 - 퍼셉트론
DNN 관련 포스팅 [AI] DNN(Deep Neural Network)의 이해 및 실습

 

합성곱 (Convolution)

  • 원래는 필터가 정해져 있고 필터를 거쳐서 나오는 것을 특징으로 활용해서 기존에 머신러닝에서 feature 추출하는 방향으로 사용을 했었는데 딥러닝에서 넘어오면서 Convolution에서 필터 자체도 학습하도록 메커니즘이 생김

  • 필터와 실제 이미지를 겹쳐서 각자 곱한 다음에 9개를 다 더해서 값이 나옴
    → W1*1 + W2*1 + W3*1 + W4*0 + W5*1 + W6*1 + W7*0 + W8*0 + W9*1
  • 기존에는 필터를 미리 정의를 해놓고 곱해서 특징을 뽑았었는데, 딥러닝에서는 필터도 학습을 함

 

원래 필터는 0과 1만 있는 게 아니라 여러 숫자가 나올 수 있고, 소수로 되어있음

 

합성곱 padding

  • Convolution을 하면 사이즈가 작아지는 현상이 발생할 수 있다.
    → 맨 외곽에 padding을 넣어주면 필터가 외곽에서 부터 시작을 하게 되는데 그럼 기존과 크기가 똑같아진다.
  • 이미지 크기를 조절하기 위해 사용한다.
  • 이미지 외곽에 어떤 것이 있는지 인식하는 학습 효과도 있음
  • padding은 기본적으로 0으로 만든다.

 

Pooling

  • Convolution layer의 출력을 입력으로 받아서 크기를 줄이거나 특정 데이터 강조
  • 이미지의 크기가 너무 크다보니 데이터를 그대로 사용하기엔 파라미터가 너무 커지고 연산도 오래걸려서 Pooling 사용으로 크기를 줄여줌
  • 학습하는 파라미터가 존재하지 않음! Convolution Layer는 학습 파라미터 존재
  • Max Pooling
    • 윈도우에서 제일 큰 값을 가지고 오는 Pooling
  • Average Pooling
    • 윈도우에서 평균 값을 가지고 오는 Pooling

→ 몇 칸 움질일지 정할 수 있고, 윈도우 사이즈(2*2)도 정할 수 있음

→ 조금씩 움직이면 더 세밀하게 되는데 차원이 커지고 연산이 많아져서 성능에는 유리할 수 있지만 속도가 느려짐

 

Pooling을 사용하면 속도가 빨라지는데 학습 속도도 빨라지고 서비스할 때 추론 속도도 빨라지게 되는데 Pooling을 많이 사용하게 되면 데이터를 없애는 것이기 때문에 데이터 손실이 일어날 수 있어서 성능에 오히려 악영향을 줄 수 있음

 

반응형

 

손글씨 데이터를 가지고 만든 CNN 구성

  • kernel = filter (55 필터 적용) → 학습해야하는 파라미터 수 : 55 = 25개 + b값 = 50개 * 채널갯수
  • channels : 필터가 여러개 → padding을 안하면 크기가 줄어든다.
  • Convolution Layer → Pooling Layer → Convolution Layer → Pooling Layer → Flattened → (dropout) → softmax Layer
    • Flattened → Dense를 하기 위해서 Flatten을 해줘야함, 1열로 세워져야 Dense가 입력으로 들어갈수 있어서 Flatten을 해줌
    • Convolution, Pooling Layer ⇒ Feature Extaction (특징 추출)
    • Fully-Connected ⇒ Classification (분류)

Convolution Layer가 의미하는게 무엇인가?? 특징을 추출하는 부분

 

CNN 실습

import tensorflow as tf

# data download
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

 

  • 이미지의 경우, 위의 코드처럼 쓰면 2차원으로 받아오는데 실제로는 3차원이 Convolution Layer에 들어가야해서 데이터를 바꿔줘야함
    • 28*28에 대한 60000개의 데이터가 x_train에 들어있어서 원래는 3차원이 들어가있는데 4차원으로 바꿔줘야함
    • Convolution을 할 때는 지금은 흑백이라서 채널이 한개짜린데 원래 이미지는 RGB 채널을 가지기때문에 채널이 기본적으로 3개가 있음! 그렇기 때문에 이미지의 input은 3차원이 들어가야하므로 reshape를 해줘야 학습이 됨
      → 2828 의 이미지에 채널 1개를 곱해서 (28*28*1) - 3차원
    • reshape : 모양을 변경하는 함수 → 기존과 바뀐 것의 데이터 총 사이즈는 같아야함
x_train = x_train.reshape((60000, 28, 28, 1)) # 60000만개의 학습 데이터
x_test = x_test.reshape((10000, 28, 28, 1))

 

원래 이미지는 RGB로 되있기 때문에 3차원인데 손글씨는 2차원이기때문에 3차원으로 변경을 해준것이다!!

그런데 Conv2D를 쓰는 이유는?
어쨋든 convolution 자체는 Convolutin 필터 사이즈가 2차원이기때문에!! 2차원으로만 컨볼루션 연산을 하기 때문에 Conv2D 함수를 쓰는거임

 

  • 모델 정의
    • Conv2D : convolution 2D 이미지를 사용
      → 32 : 채널갯수 , (5, 5) : 필터 사이즈
      → 처음에는 input_shape를 지정해줘야함
    • MaxPooling2D : 2*2 윈도우 사이즈
    • 채널갯수, hidden Layer 갯수는 임의로 넣은 값임
#model define
model = tf.keras.models.Sequential()

model.add(tf.keras.layers.Conv2D(32, (5, 5), activation='relu', input_shape=(28,28,1)))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(64, (5, 5), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
model.summary()

 

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10)

 

model.evaluate(x_test, y_test, verbose=2)

 

 

반응형

'AI > 이미지인식' 카테고리의 다른 글

[AI] Image Classification과 Backbone의 이해  (0) 2022.06.08
반응형

DNN (Deep Neural Network)

  • DNN은 입력층(input layer)과 출력층(output layer) 사이에 여러 개의 은닉층(hidden layer)들로 이뤄진 인공신경망(Artificial Neural Network, ANN)이다.
  • input에 대해서 ouput까지 Layer를 거치돼, input Layer 다음에 W랑 b가 있어서 Wx+b를 거치게 되고 hidden layer1 에서는 활성화 함수가 있다고 보면 된다.
  • 그 후 다시 Wx + b를 거치고 활성화 함수를 거친 후, output layer가 만약 분류였다면 마지막에는 softmax를 activation function(활성화 함수)을 활용한다.

 

DNN 실습

  • XOR 실습이랑 거의 비슷함
  • tensorflow import
import tensorflow as tf

tf.__version__ #tensorflow library version check
# 2.3.0 version

 

  • tensorflow에서 제공하는 데이터 활용
    • mnist라는 데이터 불러올 수 있음
    • http://yann.lecun.com/exdb/mnist/ → 여기에서 공개된 mnist dataset
    • 0부터 9까지 10개에 대한 손글씨 데이터임 → 이미지 크기는 28 x 28 (흑백이라서 채널도 하나뿐)
    • 여기서 학습 set과 test set을 나눠서 제공하기 때문에 학습 set 따로 test set 따로 받음
    • x는 이미지 실제 값
# data download
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

 

  • 실제 들어있는 값 확인 (x_train, y_train)

→ 실제로 들어있는 값 확인 가능하다. (한 줄에 28개씩 28 줄! 이렇게 데이터가 숫자로 들어감)

→ uint8 (unsigned int 8) 데이터 꼴로 들어가 있음

 

 

→ y_train 에는 5가 들어있음

→ 5번의 숫자에 대한 이미지가 x_train에 들어있음

 

 

 

  • 이미지를 분류하는 모델 생성 (XOR-2 모델과 비교)
    • XOR 모델에서는 애초에 1줄짜리 리스트가 들어있어서 shape=2 해주고 input을 넣어주면 되는데, 지금은 2차원 데이터가 들어있어서 Dense Layer 앞에서 1차원으로 되어 있어야만 들어갈 수 있는 문제가 있어서 Flatten을 해주면 input이 됨
      Flatten : 2D 이미지를 1D로 바꾸기 위해 사용
    • tf.keras.layers.Dense(128, activation='relu')
      → 위에 실제 학습할 파라미터가 들어있음
    • Dropout : 0.2는 노드를 비활성화 시킬 비율
    • softmax : 0부터 9까지 10개기 때문에 softmax를 10개로 지정해줌
#model define
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28,28)), # Flatten: 2d image -> 1d
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2), # dropout -> to reduce overfitting problem
    tf.keras.layers.Dense(10, activation='softmax')
])

# XOR-2 모델
# model = tf.keras.Sequential([
#      tf.keras.layers.Input(shape=2, dtype='float32'),
#      tf.keras.layers.Dense(4, activation='relu'),
#      tf.keras.layers.Dense(4, activation='relu'),
#      tf.keras.layers.Dense(2, activation='softmax')
# ])
반응형

Dropout 설명

기본 딥러닝
Dropout

 

→ Dropout 은 일부 노드를 끊어준다.

→ 일부 노드를 끊어주면 Overfitting될 확률이 낮아진다.

→ Dropout도 epochs 돌때마다 비활성화되는 노드들이 바뀌기 때문에 Dropout을 적용하게 되면 머신러닝에서 나왔던 Overfitting 과적합 문제가 많이 줄어든다.

Dropout은 Overfitting 과적합 문제를 줄이기 위해서 사용

 

 

  • 모델의 파라미터 개수 확인
model.summary() # 784(input_size)*128(w) + 128(b) = 100480

→ 입력 개수 x(784) * W(128) + b(128) = 100480

→ shape 하나당 b가 하나 있기 때문에 128을 더해줌

→ 입력 개수 x(128) * W(10) + b(10) = 1290

 

 

  • model.compile : 모델을 학습할 때 어떤 방식을 사용할지 정해주는 함수
    • loss='sparse_categorical_crossentropy' → cross enttopy인데 분류를 여러 개로 할 때 사용
    • metrics=['accuracy'] → 정확도를 보겠다는 것
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

 

  • 학습
    • fit() 함수를 호출할 때 추가적으로 넣을 수 있는 게 많다 (https://keras.io/ko/models/sequential/ 참고)
    • shuffle : 불리언 (각 세대를 시작하기 전 학습 데이터를 뒤섞을지 여부) 혹은 ('batch'에 넣을) 문자열
    • use_multiprocessing : 병렬 처리 관련?
model.fit(x_train, y_train, epochs=10)

→ 90점 넘게 분류가 나옴

 

 

  • 평가
    • test 데이터가 따로 있기 때문에 test 데이터를 넣어서 몇 점이 나오는지 출력
    • verbose : 어떤 방법으로 출력할지
model.evaluate(x_test, y_test, verbose=2)

→ 평가는 testset에서 94점이 나온다.

반응형
반응형

순전파 (Forword Propagation)

  • Input에서부터 Output이 나올때까지 순서대로 계산을 하는 과정
  • loss를 구하려면 실제값이랑 Output (H(x))의 차이를 알아야 한다.
  • loss를 구할 수 있다
  • 모델을 론칭을 하면 학습은 안하고 추론(예측)만 함 → 모델 추론

 

 

역전파 (Back Propagation)

  • 딥러닝에서 제일 중요한 개념★
  • 학습하는 과정에서만 사용된다.
  • 순전파와 반대로 출력층에서 입력층 방향으로 계산하면서 가중치를 업데이트 한다.
왜 반대로 가는가??
학습을 할 때 가중치를 업데이트를 하는데 만약 순전파라면 Input에서 wieght를 바꾸고 바꾼 wieght를 Hidden Layer에서 또 바꾸고 Output에서 또 바꾸는데 그러면 Output에서 loss 차이가 너무 많이 날 수 있음 !!
→ loss를 Output에서 구하는데 Input에서부터 바꾸게 되면 Hidden Layer에서 가중치를 업데이트하기 위해서는 옵티마이저를 학습하는 과정에서 미분이 있는데 그 다음층 (Output)에 미분결과가 필요한데 그 다음층 미분 결과를 알 수가 없기 때문에 순방향으로는 가중치 업데이트를 못함 !!!
→ 이 문제를 해결하기 위해 위에서부터 가중치를 미분을 해서 업데이트한 후 그 값이 그대로 내려가서 또 업데이트 하고 업데이트 하면서 가중치를 반대방향으로 업데이트를 하는 아이디어를 고안해내서 역전파가 생김
→ 층이 아무리 깊어져도 학습을 할 수 있다.
  • Gradient Descent를 활용하여 학습을 할 경우, 다음 층의 미분값이 필요하게 되는데, 현재 층에 연산이 끝나지 않아서 다음 층의 미분 값을 알 수가 없는 문제를 해결하기 위해 나옴

 

 

활성화 함수

활성화 함수 (activation function)

  • 뉴런에서 출력값을 결정하는 함수
  • 실제 뇌를 구성하는 신경 세포 뉴런이 전위가 일정치 이상이 되면 시냅스가 서로 화학적으로 연결되는 모습을 모방한 함수
    (좀 더 풀어서 설명) 실제 뇌에서는 뉴런이 전위(전기신호)에서 일정 세기 이상이 되면 시냅스가 서로 연결되면서 1이라고 하고, 아닌 경우 0이라고 하는걸 모방을 한다.
  • 만약 선형함수라면?? Wx라고 가정을 한다면 결국 층을 세번을 거치면 아래 수식처럼 나오고 그럼 W의 세제곱짜리 층 한개가 있는 거랑 W짜리 층 세개 있는거랑 똑같은 결과가 나와기때문에 층을 아무리 쌓아도 의미가 없어지기 때문에 선형함수는 사용 불가능하다.
    → 반드시 비선형 함수를 사용해야함

아무리 은닉층을 추가해도, 선형함수는 Weight만 곱해지는 효과라서 그럼 층이 세개일때는 세제곱으로 Weight가 가지고 있는 층 하나로 대체 가능하기 때문에 결국에는 의미가 없어져서 선형함수로는 활성화 함수를 쓸 수 없음

 

계단함수 (Step Function)

  • 제일 기본적이고, 실제로는 전혀 사용하지는 않음
  • 0보다 클 때는 1 , 0보다 작을 때는 0
  • 선이 하나는 아니기 때문에 비선형 함수이다.

반응형

시그모이드 함수(Sigmoid Function)

  • logistic regression 에서 활용했던 함수
  • 시그모이드 함수 하나만 쓰면 결국 로지스틱 회귀랑 똑같은게 된다.
    → 층 하나에 그 층에서 시그모이드 함수만 활성화 함수로 쓰게 된다면 로지스틱 회귀랑 똑같아지는 효과
XOR-1 실습 때(바로 전 포스팅), 층 하나만 놓고 시그모이드를 작성을 해서 모델에 넣었는데 그게 바로 로지스틱 회귀이다. 
시그모이드 함수를 여러개 쌓으면 로지스틱 회귀를 여러개 쌓은것이 됨 (그래서 중요)

  • 활성화 함수가 거치기 직전까지가 선형함수라고 생각하면 됨
    → 퍼셉트론에서 Wx + b 가 활성화 함수를 거치면서 시그모이드로 바껴서 로지스틱 회귀처럼 그래프가 바뀌는 것 때문에 로지스틱 회귀에 시그모이드 함수를 쓰는 경우

  • Sigmoid 함수는 0 또는 1에 가까워지면 그래프의 기울기가 완만해지고, 주황색 부분은 기울기가 0에 아주 가깝고 그러다 보니 역전파 과정을 거치면서 뒤에서부터 미분한 값을 앞에서 곱하는게 되는데 그런 과정을 거치다 보니 앞단에는 기울기가 잘 전달되지 않는 문제가 발생함!
    → 그 문제 : Gradient Vanishinng Problem

 

Gradient Vanishinng Problem ★

  • 시그모이드 같은 함수를 쓰게되면 기울기가 완전히 0에 수렴하게 되면서, 역전파하는 과정에서 앞으로 갈수록 기울기가 제대로 전달이 안되면서 0에 매우 가까운 값이 계속 곱해서 넘어가다보니 Weight 가 제대로 학습이 잘 안된다.
    → Gradient가 점점 사라지고 있는 문제임
  • Sigmoid 뿐만 아니라 tanh나 activation function(활성화 함수)도 시그모이드랑 비슷하게 생겨서 함수를 거치면서 출력이 점점 작아짐
  • 네트워크가 깊어질수록 더욱 심각해지는 현상이 있음
  • ReLU와 같은 activation function을 활용하면 많이 완화되는 효과가 있음

 

하이퍼볼릭탄젠트 함수 (Hyperbolic Tangent Function) - tanh

  • Sigmoid 함수랑 생긴건 똑같은데 기울기가 조금 다름 → 시그모이드는 0과1 이지만, 하이퍼볼릭찬젠트는 -1과 1 사이다
  • 시그모이드 함수보다는 적지만, 유사하게 gradient vanishing 문제 발생

 

렐루 함수(ReLU)

  • Sigmoid 함수와 tanh에서 해결못한 gradient vanishing 문제를 해결하기 위해 0보다 클때는 선형으로 0보다 작을 때는 0을 줌
  • 양수값에선 특정 값에 수렴하지 않아, 시그모이드 함수나 하이퍼볼릭탄젠트에 비해 더 잘 동작하며, gradient vanishing 문제도 많이 사라짐,, 연산도 간단하여 속도도 훨씬 빠름
  • 입력값이 음수이면 기울기가 0이 되어, 뉴런이 회생할 수 없다는 뜻의 죽은 렐루(dying ReLU)현상

 

리키 함수(Leaky ReLU)

  • ReLU를 보완하기 위한 ReLU 함수의 변형
  • 기울기가 다르되 입력값이 음수일땐 조금씩 변경하고 음력값이 양수 일 때는 크게 변경함 → 입력값이 작을때는 작게 새는 것 같은 느낌으로 값을 변형한다고 해서 Leaky 함수라고 함

 

 

Softmax 함수

  • 분류를 위해서 사용하는 함수
    → XOR-2 예제에서 앞의 Layer를 ReLu를 썼고 뒤의 Layer에서 softmax를 썼음
    → 마지막에 분류하는 Layer에서 활용되는 활성화 함수
  • 분류해야하는 정답의 개수를 k라고 할 때, k차원의 벡터를 입력받아 각 클래스에 대한 확률을 추정

→ z에 예측값들이 다양하게 나오는데 그것이 softmax Layer를 거치면 다합쳐서 1이 되도록 변경이 됨

→ 그래서 실제값은 0 1 0인데 z에서는 이상한 값이 나왔을꺼임,, 어쨋든 두번째가 0.7로 쓰기 때문에 z에서도 두번째가 제일 크긴 했을텐데 마이너스 값도 많이 나오고 하다보니 그것들을 다 합쳐서 분류에 대한 클래스에 대한 확률을 다 합쳐서 1로 만들어주도록 변경해주는 것

→ 분류에서는 softmax를 거친값이랑 실제값이랑 cross entropy 함수로 loss function을 구해준다.

반응형
반응형

JOIN

  • 두 개이상의 테이블에서 원하는 컬럼값을 검색하기 위한 기능

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 부서번호 검색

SELECT EMPNO, ENAME, SAL, DEPTNO FROM EMP;

 

DEPT 테이블에서 모든 부서의 부서번호, 부서이름, 부서위치 검색

SELECT DEPTNO, DNAME, LOC FROM DEPT;

 

 

 

EMP 테이블과 DEPT 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 부서이름, 부서위치 검색 두 개이상의 테이블에서 컬럼값을 검색하기 위해서는 반드시 조인조건을 명시하여 사용

 

카타시안 프로덕트(CATASIAN PRODUCT)

  • 조인조건을 명시하지 않은 조인 명령
  • 조인 테이블들에 대한 모든 행의 컬럼값을 교차조인하여 검색
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP, DEPT;

 

 

동등조인(EQUI JOIN)

  • 조인조건에서 조인 테이블의 컬럼값이 같을 경우 조인하여 검색 조인조건은 WHERE 구문의 조건식으로 표현하여 사용

 

EMP 테이블과 DEPT 테이블의 조인조건은 부서번호가 같은 경우 조인하여 검색

→ 테이블에 동일한 컬럼명이 존재할 경우 테이블명을 이용하여 컬럼명을 명확하게 표현

SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;

 

EMP 테이블과 DEPT 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 부서번호, 부서이름, 부서위치 검색

SELECT EMPNO, ENAME, SAL, EMP.DEPTNO, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;
SELECT EMPNO, ENAME, SAL, DEPT.DEPTNO, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;

 

조인 테이블의 동일 컬럼명을 동시에 검색할 경우 두번째 선언된 컬럼명은 자동으로 변경되어 검색

SELECT EMPNO, ENAME, SAL, EMP.DEPTNO, DEPT.DEPTNO, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;

 

조인 테이블의 동일 컬럼명을 동시에 검색할 경우 컬럼 별칭을 사용하여 검색하는 것을 권장

SELECT EMPNO, ENAME, SAL, EMP.DEPTNO EMP_DEPTNO, DEPT.DEPTNO DEPT_DEPTNO, DNAME, LOC 
    FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;

 

테이블 별칭(TABLE ALIAS)

  • 조인 테이블에 새로운 이름을 일시적으로 부여하는 기능
  • 테이블 이름을 간단하게 표현하거나 셀프 조인하기 위해 사용
  • 형식) 테이블명 별칭
  • 테이블에 별칭을 부여한 경우 해당 명령에서 실제 테이블명을 사용하면 에러 발생
SELECT EMPNO, ENAME, SAL, E.DEPTNO EMP_DEPTNO, D.DEPTNO DEPT_DEPTNO, DNAME, LOC 
    FROM EMP E, DEPT D WHERE E.DEPTNO=D.DEPTNO;

 

 

비동등 조인(NON-EQUI JOIN)

  • = 연산자를 제외한 조인조건을 사용하여 컬럼값을 비교하여 조인

 

EMP 테이블에 모든 사원의 사원번호,사원이름,급여 검색

SELECT EMPNO,ENAME,SAL FROM EMP;

 

SALGRADE 테이블에서 모든 등록의 급여등급, 최소급여, 최대급여 검색

SELECT GRADE,LOSAL,HISAL FROM SALGRADE;

 

EMP 테이블과 SALGRADE 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 급여등급 검색

조인조건 : 급여가 최소급여과 최대급여 범위에 포함될 경우 급여등급 검색

SELECT EMPNO, ENAME, SAL, GRADE FROM EMP, SALGRADE WHERE SAL BETWEEN LOSAL AND HISAL;

 

 

외부조건(OUTER JOIN)

  • 조인조건이 맞는 행만 검색하는 것이 아니라 조인조건이 맞지 않는 행도 검색하는 조인
  • 조인조건이 맞지 않는 행이 저장된 테이블에 (+)를 사용하여 컬럼값이 NULL로 검색되도록 설정

EMP 테이블에서 모든 사원의 부서번호를 중복되지 않고 하나만 검색 - 결과 : 10, 20, 30 검색(부서번호)

SELECT DISTINCT DEPTNO FROM EMP;

 

DEPT 테이블에서 모든 부서의 부서번호, 부서이름, 부서위치 검색 - 10, 20, 30, 40 검색(존재하는 모든 부서번호)

SELECT DEPTNO, DNAME, LOC FROM DEPT;

 

EMP 테이블과 DEPT 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 부서이름, 부서위치 검색

40번 부서에 근무하는 사원이 존재하지 않으므로 40번 부서에 대한 부서이름과 부서위치 미검색

SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO;

 

EMP 테이블과 DEPT 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 부서이름, 부서위치 검색

사원이 존재하지 않는 부서가 검색될 경우 사원번호, 사원이름, 급여는 NULL 검색

SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO(+)=DEPT.DEPTNO;

 

 

 

셀프조인(SELF JOIN) : 하나의 테이블에 다른 이름(TABLE ALIAS)을 여러 개 부여하여 조인

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 매니저번호(매니저의 사원번호) 검색

SELECT EMPNO,ENAME,MGR FROM EMP;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 매니저번호(매니저의 사원번호), 매니저이름(매니저의 사원이름) 검색 매니저번호에 NULL이 저장된 사원 미검색 - 검색오류

SELECT WORKER.EMPNO, WORKER.ENAME WORKER_ENAME, WORKER.MGR, MANAGER.ENAME MANAGER_ENAME
    FROM EMP WORKER, EMP MANAGER WHERE WORKER.MGR=MANAGER.EMPNO;

 

매니저번호에 NULL이 저장된 사원도 검색하기 위해 외부조인 사용

SELECT WORKER.EMPNO, WORKER.ENAME WORKER_ENAME, WORKER.MGR, MANAGER.ENAME MANAGER_ENAME
    FROM EMP WORKER, EMP MANAGER WHERE WORKER.MGR=MANAGER.EMPNO(+);

 

EMP 테이블과 DEPT 테이블에서 SALES 부서에 근무하는 사원의 사원번호, 사원이름, 급여, 부서이름, 부서위치 검색

SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP, DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO AND DNAME='SALES';

 

 

 

1999 JOIN

  • 1999년에 채택된 표준 SQL(SQL3)에 추가된 JOIN 구문

CROSS JOIN

  • 조인 테이블의 모든 행들을 교차 조인
  • 조인조건을 명시하지 않는다.
  • 형식) SELECT 검색대상,... FROM 테이블명1 CROSS JOIN 테이블명2
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP CROSS JOIN DEPT;

 

NATURAL JOIN

  • 조인 테이블에 하나의 동일한 컬럼명의 컬럼값이 같은 경우 조인
  • 형식) SELECT 검색대상,... FROM 테이블명1 NATURAL JOIN 테이블명2
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP NATURAL JOIN DEPT;

 

  • 동일한 컬럼명에 대한 테이블명 명시 불필요
SELECT EMPNO, ENAME, SAL, DEPTNO, DNAME, LOC FROM EMP NATURAL JOIN DEPT;

 

조인 테이블에 동일한 이름에 컬럼이 여러개 존재할 경우 USING 구분을 이용하여 조인 가능

형식) SELECT 검색대상,... FROM 테이블명1 JOIN 테이블명2 USING(컬럼명)

SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP JOIN DEPT USING(DEPTNO);
SELECT EMPNO, ENAME, SAL, DEPTNO, DNAME, LOC FROM EMP JOIN DEPT USING(DEPTNO);

 

INNER JOIN

  • 조건조건을 명시하여 조인조건이 맞을 경우 조인
  • 형식) SELECT 검색대상,... FROM 테이블명1 [INNER] JOIN 테이블명2 ON 조인조건
  • 조인 테이블에 같은 이름에 컬럼이 존재할 경우 테이블명을 명시하여 컬럼 표현
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP INNER JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;
SELECT EMPNO, ENAME, SAL, EMP.DEPTNO, DNAME, LOC FROM EMP INNER JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;
SELECT EMPNO, ENAME, SAL, DEPT.DEPTNO, DNAME, LOC FROM EMP INNER JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;

 

EMP 테이블과 SALGRADE 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 급여등급 검색

SELECT EMPNO, ENAME, SAL, GRADE FROM EMP JOIN SALGRADE ON SAL BETWEEN LOSAL AND HISAL;

 

EMP 테이블과 DEPT 테이블에서 SALES 부서에 근무하는 사원의 사원번호,사원이름,급여,부서이름,부서위치 검색

SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP 
	JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO WHERE DNAME='SALES';

 

OUTER JOIN

  • 조인조건을 명시하여 조인조건이 맞을 경우뿐만 아니라 맞지 않을 경우에도 조인
  • 형식) SELECT 검색대상,... FROM 테이블명1 {LEFT|RIGTH|FULL} [OUTER] JOIN 테이블명2 ON 조인조건
  • LEFT OUTER JOIN : 왼쪽 방향에 선언된 조인 테이블의 모든 행을 검색하되 조인조건이 맞지 않는 오른쪽방향의 테이블 행에 컬럼값은 NULL 검색
  • RIGTH OUTER JOIN : 오른쪽 방향에 선언된 조인 테이블의 모든 행을 검색하되 조인조건이 맞지 않는 왼쪽방향의 테이블 행에 컬럼값은 NULL 검색
  • FULL OUTER JOIN : 양쪽 방향에 선언된 조인 테이블의 모든 행을 검색하되 조인조건이 맞지 않는 왼쪽 또는 오른쪽 방향의 테이블 행에 컬럼값은 NULL 검색
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP LEFT OUTER JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP RIGHT OUTER JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;
SELECT EMPNO, ENAME, SAL, DNAME, LOC FROM EMP FULL OUTER JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 매니저번호, 매니저이름 검색 - SELF JOIN

SELECT WORKER.EMPNO, WORKER.ENAME WORKER_ENAME, WORKER.MGR, MANAGER.ENAME MANAGER_ENAME
    FROM EMP WORKER JOIN EMP MANAGER ON WORKER.MGR=MANAGER.EMPNO;
SELECT WORKER.EMPNO, WORKER.ENAME WORKER_ENAME, WORKER.MGR, MANAGER.ENAME MANAGER_ENAME
    FROM EMP WORKER LEFT JOIN EMP MANAGER ON WORKER.MGR=MANAGER.EMPNO;

 

 

SUBQUERY

  • SQL 명령에 포함되어 실행되는 SELECT 명령
  • 여러번의 SQL 명령으로 얻을 수 있는 결과를 하나의 SQL 명령으로 얻기 위해 사용하는 기능
  • SELECT 명령(MAINQUERY)에 포함되어 실행되는 SELECT 명령(SUBQUERY)
  • SUBQUERY 명령 실행 후 MAINQUERY 명령 실행
  • SELECT 명령에서 SUBQUERY 명령은 FROM, WHERE, HAVING 구문에서 ( ) 안에 작성

 

EMP 테이블에서 사원이름이 SCOTT인 사원보다 많은 급여를 받는 사원의 사원번호, 사원이름, 급여 검색

  • WHERE 구문에서 조건식의 비교값 대신 SUBQUERY 명령의 결과값으로 사용
  • 조건식의 비교대상과 같은 자료형의 값이 하나만 검색되도록 SUBQUERY 명령 작성
SELECT EMPNO, ENAME, SAL FROM EMP WHERE SAL>(SELECT SAL FROM EMP WHERE ENAME='SCOTT');

 

EMP 테이블에서 사원번호 7844인 사원과 같은 업무를 하는 사원의 사원번호, 사원이름, 업무, 급여 검색

SELECT EMPNO, ENAME, JOB, SAL FROM EMP 
    WHERE JOB=(SELECT JOB FROM EMP WHERE EMPNO=7844) AND EMPNO<>7844;

 

EMP 테이블에서 사원번호가 7521인 사원과 같은 업무를 하는 사원 중 사원번호 7900인 사원보다 많은 급여를 받는 사원의 사원번호, 사원이름, 업무, 급여 검색

SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE JOB=(SELECT JOB FROM EMP WHERE EMPNO=7521)
    AND EMPNO<>7521 AND SAL>(SELECT SAL FROM EMP WHERE EMPNO=7900);

 

EMP 테이블에서 SALES 부서에 근무하는 사원의 사원번호, 사원이름, 업무, 급여 검색

  • 부서이름은 DEPT 테이블에 저장되어 있으므로 테이블 조인을 이용하여 검색
SELECT EMPNO, ENAME, JOB, SAL FROM EMP JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO WHERE DNAME='SALES'; 
  • 테이블 조인 대신 서브쿼리를 사용하여 검색
SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES');

 

EMP 테이블에서 급여를 가장 적게 받는 사원의 사원번호, 사원이름, 업무, 급여 검색

SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE SAL=(SELECT MIN(SAL) FROM EMP);

 

EMP 테이블에서 SALES 부서에 근무하는 사원 중 가장 많은 급여를 받는 사원의 사원번호, 사원이름, 업무, 급여 검색

오라클은 서브쿼리 내부에 다른 서브쿼리 사용 가능

SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE SAL=
    (SELECT MAX(SAL) FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES'));

 

EMP 테이블에서 부서별 평균 급여 중 가장 많은 평균 급여를 받는 부서의 부서번호, 평균급여 검색

SELECT DEPTNO, CEIL(AVG(SAL)) AVG_SAL FROM EMP GROUP BY DEPTNO 
    HAVING AVG(SAL)=(SELECT MAX(AVG(SAL)) FROM EMP GROUP BY DEPTNO);

 

 

 

반응형

'DB > Oracle' 카테고리의 다른 글

[Oracle] 오라클 다운로드 후 작업  (0) 2022.06.08
[Oracle] Oracle 함수  (0) 2020.12.02
[Oracle] Oracle 기본 문법  (0) 2020.12.01
반응형

함수(FUNCTION)

  • 값을 전달받아 처리하여 결과값을 반환하는 기능을 제공

 

단일함수

  • 하나의 값을 전달받아 처리하여 결과값을 반환하는 함수
  • 문자함수, 숫자함수, 날짜함수, 변환함수, 일반함수

그룹함수 : 여러 개의 값을 전달받아 처리하여 결과값을 반환하는 함수

문자함수 : 문자형 상수를 전달받아 처리하여 결과를 반환하는 함수

 

UPPER (문자상수) : 전달받은 문자형 상수를 모두 대문자로 변환하여 반환하는 함수

LOWER (문자상수) : 전달받은 문자형 상수를 모두 소문자로 변환하여 반환하는 함수

SELECT ENAME, UPPER(ENAME), LOWER(ENAME) FROM EMP WHERE ENAME = 'SCOTT';

 

문자형 상수는 대소문자를 구분함

UPPER 함수 또는 LOWER 함수를 이용하여 대소문자 구분 없이 비교하여 검색 가능

SELECT EMPNO,ENAME,SAL FROM EMP WHERE UPPER(ENAME) = UPPER('smith');

 

INITCAP (문자상수) : 문자형 상수를 전달받아 첫문자만 대문자로 변환하고 나머지는 소문자로 변환하여 반환하는 함수

SELECT ENAME, INITCAP(ENAME) FROM EMP;

 

CONCAT (문자상수,문자상수)

  • 두개의 문자형 상수를 결합하여 반환하는 함수
  • || 기호와 동일한 기능 제공
SELECT ENAME, JOB, CONCAT(ENAME, JOB), ENAME || JOB FROM EMP;

 

SUBSTR(문자상수, 시작위치, 갯수) : 문자형 상수에서 시작위치(INDEX)부터 갯수만큼의 문자를 분리하여 반환하는 함수

SELECT EMPNO, ENAME, JOB, SUBSTR(JOB, 6, 3) FROM EMP WHERE EMPNO=7499;

 

LENGTH(문자상수) : 문자형 상수의 문자갯수를 반환하는 함수

SELECT EMPNO, ENAME, LENGTH(ENAME) FROM EMP WHERE EMPNO=7499;

 

INSTR(문자상수, 검색문자, 시작위치, 검색갯수)

  • 문자형 상수에서 검색문자를 시작위치부터 검색하여 검색갯수의 시작위치(INDEX)를 반환하는 반환하는 함수
  • 검색문자가 없는 경우 0 반환
SELECT EMPNO, ENAME, JOB, INSTR(JOB, 'A', 1, 2) FROM EMP WHERE EMPNO=7499;

 

LPAD(문자상수, 자릿수, 채울문자) : 문자형 상수를 자릿수만큼의 길이로 오른쪽 정렬하여 검색하되 왼쪽 남은 자릿수는 채울문자로 채워 반환하는 함수

RPAD(문자상수, 자릿수, 채울문자) : 문자형 상수를 자릿수만큼의 길이로 왼쪽 정렬하여 검색하되 오른쪽 남은 자릿수는 채울문자로 채워 반환하는 함수

SELECT EMPNO, ENAME, SAL, LPAD(SAL, 8, '*'), RPAD(SAL, 8, '*') FROM EMP WHERE EMPNO=7844;

 

TRIM( {LEADING | TRAILING} 제거문자 FROM 문자상수) : 문자상수의 앞(LEADING) 또는 뒤(TRAILING)에 존재하는 제거문자를 모두 없애고 반환하는 함수

SELECT EMPNO, ENAME, JOB, TRIM(LEADING 'S' FROM JOB) , TRIM(TRAILING 'N' FROM JOB) FROM EMP WHERE EMPNO=7844;

 

REPLACE(문자상수, 검색문자, 변환문자) : 문자형 상수에 검색문자를 찾아 변환문자로 변환하여 반환하는 함수

SELECT EMPNO, ENAME, JOB, REPLACE(JOB, 'MAN', 'PERSON') FROM EMP WHERE EMPNO=7844;

 

 

숫자함수 : 숫자형 상수를 전달받아 처리하여 결과값을 반환하는 함수

 

ROUND(숫자상수, 소수점자릿수)

  • 숫자형 상수를 소숫점 자릿수만큼 검색되도록 반올림하여 반환하는 함수

DUAL

  • 가상테이블
  • 테이블 없이 SELECT 명령을 작성할 경우 사용하는 테이블
SELECT 45.582, ROUND(45.582, 2), ROUND(45.582, 0), ROUND(45.582, -1) FROM DUAL;

 

TRUNC(숫자상수, 소수점자릿수) : 숫자형 상수를 소숫점 자릿수만큼 검색되도록 절삭하여 반환하는 함수

SELECT 45.582, TRUNC(45.582, 2), TRUNC(45.582, 0), TRUNC(45.582, -1) FROM DUAL;

 

CEIL(숫자상수) : 숫자형 상수에서 소숫점 이하 값이 존재할 경우 증가하여 정수값으로 반환하는 함수

SELECT 15.3, CEIL(15.3), CEIL(-15.3) FROM DUAL;

 

FLOOR(숫자상수) : 숫자형 상수에서 소숫점 이하 값이 존재할 경우 감소하여 정수값으로 반환하는 함수

SELECT 15.3, FLOOR(15.3), FLOOR(-15.3) FROM DUAL;

 

MOD(숫자상수, 숫자상수) : 숫자형 상수를 나누어 나머지를 반환하는 함수

SELECT 20/8, MOD(20, 8) FROM DUAL;
--정수값을 나눈 결과로 실수값 발생 가능

 

POWER(숫자상수, 숫자상수) : 숫자형 상수의 제곱근을 계산하여 반환하는 함수

SELECT 3*3*3*3*3, POWER(3, 5) FROM DUAL;

 

 

날짜함수

  • 날짜형 상수를 전달받아 처리하여 반환하는 함수

SYSDATE

  • 시스템의 현재 날짜와 시간정보를 제공하기 위한 키워드
  • 자료형이 날짜형인 경우 표면적으로 'RR/MM/DD'로 표현되지만 내부적으로 날짜와 시간정보 저장
SELECT SYSDATE FROM DUAL;

 

ADD_MONTHS(날짜상수, 숫자상수) : 날짜형 상수에 숫자형 상수만큼의 개월수를 더한 결과를 반환하는 함수

SELECT SYSDATE, ADD_MONTHS(SYSDATE, 5) FROM DUAL;

 

NEXT_DAY(날짜상수, 요일) : 날짜형 상수에서 다가오는 특정 요일의 날짜를 반환하는 함수

SELECT SYSDATE, NEXT_DAY(SYSDATE, '토') FROM DUAL;

 

오라클에 접속된 사용자 환경(세션 : SESSION)에 따라 날짜와 시간정보를 다르게 표현 가능

세션의 날짜에 대한 표현 언어 변경

ALTER SESSION SET NLS_LANGUAGE='AMERICAN'; 
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'SAT') FROM DUAL;

ALTER SESSION SET NLS_LANGUAGE='KOREAN'; 
SELECT SYSDATE, NEXT_DAY(SYSDATE, '토') FROM DUAL;

 

 

TRUNC(날짜상수, 표현단위) : 날짜형 상수를 원하는 단위까지만 표현하며 나머지는 초기값으로 반환하는 함수

SELECT SYSDATE, TRUNC(SYSDATE, 'MONTH'), TRUNC(SYSDATE, 'YEAR') FROM DUAL;

 

날짜형 상수는 연산 가능

날짜상수 + 숫자상수 = 날짜상수  일 증가

SELECT SYSDATE, SYSDATE + 7 FROM DUAL;

 

날짜상수 + 숫자상수/24 = 날짜상수  시간 증가

SELECT SYSDATE, SYSDATE + 100/24 FROM DUAL;

 

날짜상수 - 숫자상수 = 날짜상수  일 감소

SELECT SYSDATE, SYSDATE - 7 FROM DUAL;

 

날짜상수 - 숫자상수/24 = 날짜상수  시간 감소

SELECT SYSDATE, SYSDATE - 100/24 FROM DUAL;

 

날짜상수 - 날짜상수 = 숫자상수  일(실수)

SELECT EMPNO, ENAME, HIREDATE, SYSDATE-HIREDATE FROM EMP WHERE EMPNO=7499; 
SELECT EMPNO, ENAME, HIREDATE, CEIL(SYSDATE-HIREDATE) || '일' "근속일수" FROM EMP WHERE EMPNO=7499;

 

 

 

변환함수

  • 전달받은 상수를 원하는 자료형의 상수로 변환하여 반환하는 함수

TO_NUMBER(문자상수)

  • 문자형 상수를 전달받아 숫자형 상수로 변환하여 반환하는 함수
  • 전달받은 문자형 상수가 숫자가 아닌 경우 에러 발생
SELECT EMPNO, ENAME, SAL FROM EMP WHERE EMPNO=7839;

 

비교 컬럼의 자료형이 숫자형인 경우 비교값이 문자형 상수인 경우 숫자형 상수로 변환하여 비교 - 강제 형변환

SELECT EMPNO,ENAME,SAL FROM EMP WHERE EMPNO=TO_NUMBER('7839');

비교 컬럼의 자료형이 숫자형인 경우 비교값이 문자형 상수라면 자동으로 숫자형 상수로 변환하여 비교 - 자동 형변환

SELECT EMPNO,ENAME,SAL FROM EMP WHERE EMPNO='7839';

 

EMP 테이블에서 사원번호가 7839인 사원의 사원번호, 사원이름, 급여, 급여*0.9 검색

SELECT EMPNO, ENAME, SAL, SAL*0.9 FROM EMP WHERE EMPNO=7839; 
SELECT EMPNO, ENAME, SAL, SAL*TO_NUMBER('0.9') FROM EMP WHERE EMPNO=7839; 
SELECT EMPNO, ENAME, SAL, SAL*'0.9' FROM EMP WHERE EMPNO=7839;

 

문자형 상수를 계산할 경우 자동으로 숫자형 상수로 변환 

SELECT '10'+'20' FROM DUAL;

 

TO_DATE (문자상수 [,패턴기호])

  • 문자형 상수를 전달받아 날짜형 상수로 변환하여 반환하는 함수
  • 문자형 상수가 날짜 형식가 아닌 경우 에러 발생 - 기본적으로 'RR/MM/DD' 형식으로 표현

 

비교 컴럼의 자료형이 날짜형인 경우 비교값이 문자형 상수인 경우 날짜형 상수로 변환하여 비교 - 강제 형변환

SELECT EMPNO, ENAME, HIREDATE FROM EMP WHERE HIREDATE=TO_DATE('82/01/23');

비교 컴럼의 자료형이 날짜형인 경우 비교값이 문자형 상수라면 자동으로 날짜형 상수로 변환하여 비교 - 자동 형변환 

SELECT EMPNO,ENAME,HIREDATE FROM EMP WHERE HIREDATE='82/01/23';

 

 

'RR/MM/DD' 형식 대신 'YYYY-MM-DD' 형식으로 표현 가능 

SELECT EMPNO, ENAME, HIREDATE FROM EMP WHERE HIREDATE='1982-01-23';

 

TO_DATE 함수의 패턴기호를 이용하여 원하는 형식의 날짜형 상수로 표현 가능

SELECT EMPNO, ENAME, HIREDATE FROM EMP WHERE HIREDATE=TO_DATE('01-23-1982', 'MM-DD-YYYY');

 

EMP 테이블에서 사원번호가 7844인 사원의 사원번호, 사원이름, 입사일, 입사일로부터 2000년 1월 1일까지 근무한 일자를 계산하여 검색

SELECT EMPNO, ENAME, HIREDATE, TO_DATE('2000-01-01') - HIREDATE FROM EMP WHERE EMPNO=7844;

 

TO_CHAR( {숫자상수|날짜상수}, 패턴기호)

  • 전달받은 숫자형 상수 또는 날짜형 상수를 패턴기호 형식의 문자형 상수로 변환하여 반환하는 함수

날짜패턴기호 : YYYY(년), RR(년), MM(월), DD(일), HH24(시), HH12(시), AM(오전), PM(오후), MI(분), SS(초)

SELECT SYSDATE FROM DUAL; 
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD') FROM DUAL; 
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;

 

EMP 테이블에서 1981년도에 입사한 사원의 정보 검색

세션의 날짜형 표현방식(NLS_DATE_FORMAT)이 'RR/MM/DD' 형식일 경우에만 가능

SELECT * FROM EMP WHERE HIREDATE LIKE '81%';

날짜패턴기호를 이용하여 원하는 날짜값만 반환받아 문자형 상수로 비교

SELECT * FROM EMP WHERE TO_CHAR(HIREDATE, 'YYYY')='1981';

 

숫자패턴기호

  • 9(숫자 또는 공백), 0(숫자), L(화폐단위), $(달러)
  • 자릿수가 모자란 경우 #으로 표현
SELECT 100000000, TO_CHAR(100000000, '999,999,990' ) FROM DUAL;

 

EMP 테이블에서 사원번호가 7844인 사원의 사원번호,사원이름,급여 검색

SELECT EMPNO, ENAME, SAL FROM EMP WHERE EMPNO=7844; 
SELECT EMPNO, ENAME, TO_CHAR(SAL,'999,990') SAL FROM EMP WHERE EMPNO=7844; 
SELECT EMPNO, ENAME, TO_CHAR(SAL,'L99,990') SAL FROM EMP WHERE EMPNO=7844; 
SELECT EMPNO, ENAME, TO_CHAR(SAL,'$99,990.00') SAL FROM EMP WHERE EMPNO=7844;

 

일반함수 : 전달값이 특정 조건일 경우 처리하여 결과를 반환하는 함수

 

NVL(전달값, 변경값) : 전달값이 NULL인 경우 변경값으로 변환하여 반환하는 함수

변경값은 전달값의 자료형과 동일한 자료형의 값으로 변경하지 않으면 에러 발생

 

EMP 테이블에서 모든 사원의 사원번호,사원이름,연봉((급여+성과급)*12) 검색

NVL 함수를 이용하여 성과급이 NULL인 경우 0으로 변환하여 연산

SELECT EMPNO, ENAME, (SAL+NVL(COMM, 0)) * 12 ANNUAL FROM EMP;

 

NVL2(전달값, 변경값1, 변경값2) : 전달값이 NULL이 아닌 경우 변경값1로 변환하고 NULL인 경우 변경값2로 변환하여 반환하는 함수

SELECT EMPNO, ENAME, (SAL+NVL2(COMM, COMM, 0))*12 ANNUAL FROM EMP; 
SELECT EMPNO, ENAME, NVL2(COMM, (SAL+COMM)*12, SAL*12) ANNUAL FROM EMP;

 

DECODE(전달값, 비교값1, 변경값1, 비교값2, 변경값2, ...[,기본변경값])

  • 전달값을 비교값과 차례대로 비교하여 같은 경우 변경값으로 변환하여 반환하는 함수
  • 같은 비교값이 없는 경우 기본 변경값으로 변환하여 반환 - 기본 변경값이 생략된 경우 NULL 반환

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 업무, 급여, 업무별 실급여 검색

업무별 실급여 : 업무별로 급여를 다시 계산하여 실제로 지불할 급여

ANALYST : 급여*1.1, CLERK : 급여*1.2, MANAGER : 급여*1.3, PRESIDENT : 급여*1.4, SALESMAN : 급여*1.5

SELECT EMPNO, ENAME, JOB, SAL, DECODE(JOB, 'ANALYST', SAL*1.1, 'CLERK', SAL*1.2 , 'MANAGER', SAL*1.3, 'PRESIDENT', SAL*1.4, 'SALESMAN', SAL*1.5, SAL) "업무별 실급여" FROM EMP;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 업무별 급여 검색

해당 업무가 아닌 경우 NULL 검색

SELECT EMPNO, ENAME, DECODE(JOB, 'ANALYST', SAL) ANALYST , DECODE(JOB, 'CLERK', SAL) CLERK, DECODE(JOB, 'MANAGER', SAL) MANAGER , DECODE(JOB, 'PRESIDENT', SAL) PRESIDENT, DECODE(JOB, 'SALESMAN', SAL) SALESMAN FROM EMP;

 

 

그룹함수

  • 값을 여러개 전달받아 처리하여 결과를 반환하는 함수

 

COUNT(전달값)

  • 전달값의 갯수를 반환하는 함수 - 검색행의 갯수 반환
  • 다른 검색대상과 그룹함수를 동시에 사용 불가능 : 검색행의 갯수가 다르므로 에러 발생
  • 그룹함수는 NULL이 전달될 경우 값으로 인식되지 않아 미처리
SELECT COUNT(EMPNO) FROM EMP;

 

전달값으로 * 기호를 사용하여 모든 컬럼값으로 행의 갯수를 계산하여 반환

SELECT COUNT(*) FROM EMP;

 

MAX(전달값) : 전달값 중 최대값을 반환하는 함수

SELECT MAX(SAL) FROM EMP; 
SELECT MAX(ENAME) FROM EMP; 
SELECT MAX(HIREDATE) FROM EMP;

 

MIN(전달값) : 전달값 중 최소값을 반환하는 함수

SELECT MIN(SAL) FROM EMP; 
SELECT MIN(ENAME) FROM EMP; 
SELECT MIN(HIREDATE) FROM EMP;

 

SUM(전달값) : 숫자형 상수를 전달받아 전달값의 합계를 계산하여 반환하는 함수

SELECT SUM(SAL) FROM EMP;

 

AVG(전달값) : 숫자형 상수를 전달받아 전달값의 평균을 계산하여 반환하는 함수

SELECT AVG(SAL) FROM EMP; 
SELECT ROUND(AVG(SAL), 2) FROM EMP;

 

EMP 테이블에서 모든 사원의 평균 성과급 검색

성과급이 NULL이 아닌 사원의 평균 성과급 검색 - 검색오류

SELECT AVG(COMM) FROM EMP;

 

NVL 함수를 이용하여 성과급이 NULL인 경우 0으로 변환하여 평균 성과급 검색

SELECT AVG(NVL(COMM, 0)) FROM EMP; 
SELECT CEIL(AVG(NVL(COMM, 0))) "평균 성과급" FROM EMP;

 

GROUP BY

  • 그룹함수를 사용할 경우 컬럼값으로 그룹을 세분화하여 검색하기 위해 사용
  • 컬럼값이 같은 경우 같은 그룹으로 처리되어 검색하는 구문
  • 형식) SELECT 그룹함수[,검색대상],... FROM 테이블명,... [WHERE 조건식] GROUP BY {컬럼명|연산식|함수},... [ORDER BY {컬럼명|연산식,함수,위치값,별칭} {ASC|DESC},... ]

 

GROUP BY 구문에서 사용된 그룹 지정 표현식은 검색대상으로 사용 가능 - 권장

SELECT DEPTNO, COUNT(*) FROM EMP GROUP BY DEPTNO;

컬럼의 별칭을 GROUP BY 구분에서 사용할 경우 에러 발생

SELECT DEPTNO DNO, COUNT(*) FROM EMP GROUP BY DNO;

 

EMP 테이블에서 모든 사원의 업무별 평균 급여 검색

SELECT JOB, CEIL(AVG(SAL)) AVG_SAL FROM EMP GROUP BY JOB;

 

EMP 테이블에서 업무가 PRESIDENT인 사원의 제외한 사원들의 업무별 평균 급여 검색

SELECT JOB, CEIL(AVG(SAL)) AVG_SAL FROM EMP WHERE JOB<>'PRESIDENT' GROUP BY JOB;

 

EMP 테이블에서 업무가 PRESIDENT인 사원의 제외한 사원들의 업무별 평균 급여를 평균 급여로 내림차순 정렬하여 검색

SELECT JOB, CEIL(AVG(SAL)) AVG_SAL FROM EMP WHERE JOB<>'PRESIDENT' GROUP BY JOB ORDER BY AVG_SAL DESC;

 

SUM : EMP 테이블에서 모든 사원의 부서별 급여 합계 검색

SELECT DEPTNO, SUM(SAL) FROM EMP GROUP BY DEPTNO;

 

HAVING

  • GROUP BY 구문으로 세분화되어 검색된 결과의 그룹 조건을 부여하여 검색
  • 형식) SELECT 그룹함수[,검색대상],... FROM 테이블명,... [WHERE 조건식] GROUP BY {컬럼명|연산식|함수},... HAVING 그룹조건식 [ORDER BY {컬럼명|연산식,함수,위치값,별칭} {ASC|DESC},... ]

 

EMP 테이블에서 모든 사원의 부서별 급여 합계 중 부서별 급여 합계가 9000 이상인 경우에만 검색

SELECT DEPTNO, SUM(SAL) FROM EMP GROUP BY DEPTNO HAVING SUM(SAL)>=9000;

 

EMP 테이블에서 업무가 PRESIDENT인 사원의 제외한 사원들의 업무별 평균 급여 검색

SELECT JOB, CEIL(AVG(SAL)) AVG_SAL FROM EMP WHERE JOB<>'PRESIDENT' GROUP BY JOB; 
SELECT JOB, CEIL(AVG(SAL)) AVG_SAL FROM EMP GROUP BY JOB HAVING JOB<>'PRESIDENT';

 

분석함수

  • 윈도우함수(그룹함수, 순서함수, 순위함수 등)에 의해 발생된 값을 제공받아 처리하여 결과를 반환하는 함수
  • 형식) SELECT 윈도우함수 OVER ([PARTITION BY 컬럼명] [ORDER BY 컬럼명] [WINDOWING]), 검색대상, ... FROM 테이블명

 

MAX( )

EMP 테이블에서 모든 사원의 급여 중 가장 많은 급여 검색

SELECT MAX(SAL) FROM EMP;

 

EMP 테이블에서 모든 사원 중 가장 많은 급여를 받는 사원의 사원번호, 사원이름, 급여 검색

그룹함수를 사용할 경우 다른 검색대상을 작성할 경우 에러 발생

SELECT EMPNO, ENAME, MAX(SAL) FROM EMP;

 

SELECT 명령을 여러 번 사용하여 가장 많은 급여를 받는 사원의 사원번호, 사원이름, 급여 검색 가능

SELECT MAX(SAL) FROM EMP; --검색결과 : 5000
SELECT EMPNO, ENAME, SAL FROM EMP WHERE SAL=5000;

 

OVER( )

그룹함수를 분석함수와 같이 사용할 경우 다른 검색대상 사용 가능

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 최대급여 검색

SELECT EMPNO, ENAME, SAL, MAX(SAL) OVER() FROM EMP;

 

AVG( )

EMP 테이블에서 모든 사원의 부서별 평균 급여 검색

SELECT DEPTNO, CEIL(AVG(SAL)) "부서별 평균 급여" FROM EMP GROUP BY DEPTNO;

# CEIL() 함수는 이전 포스팅 글에 나와있음

 

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 부서번호, 부서별 평균 급여 검색

분석함수를 사용할 경우 GROUP BY 구문 사용 불가능

SELECT EMPNO, ENAME, SAL, DEPTNO, CEIL(AVG(SAL) OVER()) "부서별 평균 급여" FROM EMP GROUP BY DEPTNO;

 

분석함수에서는 GROUP BY 구문 대신 PARTITION BY 기능을 제공

SELECT EMPNO, ENAME, SAL, DEPTNO, CEIL(AVG(SAL) OVER(PARTITION BY DEPTNO)) "부서별 평균 급여" FROM EMP;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 급여합계를 급여로 내림차순 정렬하여 검색

SELECT EMPNO, ENAME, SAL, SUM(SAL) OVER() "급여합계" FROM EMP ORDER BY SAL DESC;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 순차적 누적 급여합계를 급여로 내림차순 정렬하여 검색

  • OVER 함수에서 ORDER BY 기능을 이용하면 정렬하면서 윈도우 함수의 결과를 차례대로 반환
  • 정렬값이 동일한 경우 윈도우 함수의 동시 처리 결과값 반환
SELECT EMPNO, ENAME, SAL, SUM(SAL) OVER(ORDER BY SAL DESC) "순차적 누적 급여합계" FROM EMP;

 

정렬값이 동일한 경우 다른 정렬값을 제공하면 동시 처리 결과값 미반환

SELECT EMPNO, ENAME, SAL, SUM(SAL) OVER(ORDER BY SAL DESC, ENAME) "순차적 누적 급여합계" FROM EMP;

 

OVER 함수에 WINDOWING 기능을 이용하면 정렬값이 동일한 경우에도 동시 처리 결과값 반환 방지

  • WINDOWING : 순차적인 검색행을 기준으로 이전 또는 이후에 존재하는 행(범위)을 표현하는 기능
  • ROWS UNBOUNDED PRECEDING : 검색행을 기준으로 이전에 존재하는 모든 행만을 검색대상으로 설정
SELECT EMPNO, ENAME, SAL, SUM(SAL) OVER(ORDER BY SAL DESC ROWS UNBOUNDED PRECEDING) "순차적 누적 급여합계" FROM EMP;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 검색사원의 급여와 검색사원의 직전 사원 급여와 검색사원의 직후 사원 급여의 합계를 급여로 오름차순 정렬하여 검색

SELECT EMPNO, ENAME, SAL, SUM(SAL) OVER
    (ORDER BY SAL ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) "부분합계" FROM EMP;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 검색사원의 급여보다 100 작거나 200 큰 사원의 인원수를 급여로 오름차순 정렬하여 검색

SELECT EMPNO, ENAME, SAL, COUNT(*) OVER
    (ORDER BY SAL RANGE BETWEEN 100 PRECEDING AND 200 FOLLOWING)-1 "인원수" FROM EMP;

 

 

 

순위함수

  • RANK, DENSE_RANK, ROW_NUMBER
  • 분석함수와 같이 사용해야 되는 함수

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 급여순위를 급여로 내림차순 정렬하여 검색

RANK 함수 : 정렬값이 동일한 경우 같은 순위로 지정하며 다음 순위를 건너뛰고 검색하는 함수

SELECT EMPNO, ENAME, SAL, RANK() OVER(ORDER BY SAL DESC) 급여순위 FROM EMP;

 

DENSE_RANK 함수 : 정렬값이 동일한 경우 같은 순위로 지정하며 다음 순위로 검색하는 함수

SELECT EMPNO, ENAME, SAL, DENSE_RANK() OVER(ORDER BY SAL DESC) 급여순위 FROM EMP;    

 

ROW_NUMBER 함수 : 정렬값이 동일한 경우 다른 순위로 지정하여 검색하는 함수 - 행번호 지정

SELECT EMPNO, ENAME, SAL, ROW_NUMBER() OVER(ORDER BY SAL DESC) 급여순위 FROM EMP;   

 

 

순서함수

  • FIRST_VALUE, LAST_VALUE, LAG, LEAD
  • 분석함수와 같이 사용해야 되는 함수

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 급여를 가장 많이 받는 사원의 사원이름, 급여를 가장 적게 받는 사원이름을 급여로 내림차순 정렬하여 검색

  • FIRST_VALUE 함수 : 첫번째 검색행의 컬럼값을 반환하는 함수
  • LAST_VALUE 함수 : 마지막 검색행의 컬럼값을 반환하는 함수
SELECT EMPNO, ENAME, SAL, FIRST_VALUE(ENAME) OVER(ORDER BY SAL DESC) MAX_ENAME
    ,LAST_VALUE(ENAME) OVER(ORDER BY SAL DESC ROWS BETWEEN CURRENT ROW 
    AND UNBOUNDED FOLLOWING) MIN_ENAME FROM EMP;

 

EMP 테이블에서 모든 사원의 사원번호, 사원이름, 급여, 검색사원 직전 사원의 급여, 검색사원 직후 사원의 급여를 급여로 내림차순 정렬하여 검색

  • LAG 함수 : 검색행 이전 행의 컬럼값을 반환하는 함수
    • 형식) LAG(컬럼명, 이전행위치, 변경값) : 이전 위치의 행에 컬럼값을 반환하되 이전 행이 없으면 변경값 반환
  • LEAD 함수 : 검색행 이후 행의 컬럼값을 반환하는 함수
    • 형식) LEAD(컬럼명, 이전행위치, 변경값) : 이후 위치의 행에 컬럼값을 반환하되 이후 행이 없으면 변경값 반환
SELECT EMPNO, ENAME, SAL, LAG(SAL,1,0) OVER(ORDER BY SAL DESC) BEFORE_SAL
    ,LEAD(SAL,1,0) OVER(ORDER BY SAL DESC) AFTER_SAL FROM EMP;

 

반응형

'DB > Oracle' 카테고리의 다른 글

[Oracle] 오라클 다운로드 후 작업  (0) 2022.06.08
[Oracle] JOIN과 서브쿼리  (0) 2020.12.03
[Oracle] Oracle 기본 문법  (0) 2020.12.01

+ Recent posts