[SQLP] SQL 기본

당당·2024년 4월 18일
0

SQLP

목록 보기
3/12

📔설명

관계형 데이터베이스, SELECT, 함수, WHERE, GROUP BY, ORDER BY절, 조인 등을 알아보자!


🥞관계형 데이터베이스 개요

1. 데이터베이스

넓은 의미의 데이터베이스 : 일상적인 정보를 모아 놓은 것 자체

일반적 데이터베이스 : 필요에 따라 데이터를 일정한 형태로 저장해 놓은 것

DBMS(Database Management System) : 데이터 손상을 피하고, 필요한 데이터를 복구해주는 소프트웨어 등 데이터 관리에 관한 시스템

파일 시스템

  • 동일한 데이터가 여러 곳에 저장되는 문제 발생
  • 변경 작업이 발생시 모든 복사본 파일에 변경 작업을 한꺼번에 병행 처리X시 데이터 불일치성 발생

관계형 데이터베이스

  • 정규화를 통한 이상현상 제거, 데이터 중복 피함
  • 동시성 관리병행 제어를 통해 많은 사용자가 데이터를 동시에 공유 및 조작 가능하게 함
  • 데이터의 성격, 속성 또는 표현 방법 등을 체계화
  • 데이터 표준화를 통한 데이터 품질 확보
  • 인증된 사용자만 참조할 수 있도록 보안 기능 제공
  • 테이블 생성 시 사용 가능한 다양한 제약조건으로 위배 데이터 입력 방지, 관계 연결 데이터 삭제 방지 등 데이터 무결성 보장
  • 장애로부터 사용자가 입력,수정,삭제한 데이터가 반영될 수 있도록 보장
  • 시스템 다운, 재해 상황에서 데이터 복구 가능

2. SQL

SQL(Structured Query Language) : 관계형 데이터베이스에서 데이터 정의, 데이터 조작, 데이터 제어를 위해 사용하는 언어
=> 데이터집합으로 취급
(ex. 포지션이 미드필더인 선수 정보 검색시 선수라는 집합에서 조건을 만족하는 요구 집합을 추출)


3. STANDARD SQL 개요

일반 집합 연산자

  • UNION 연산UNION기능으로
  • INTERSECTION 연산INTERSECT 기능으로
  • DIFFERENCE 연산EXCEPT(MINUS) 기능으로
  • PRODUCT 연산CROSS JOIN기능으로 구현

UNION : 합집합을 제공하고, 공통 교집합의 중복 제거
UNION ALL : 공통집합을 중복해 보여줌
INTERSECTION : 두 집합의 공통집합
DIFFERENCE : 첫 번째 집합에서 두 번째 집합과의 공통집합을 제외
PRODUCT : JOIN 조건이 없는 경우 생길 수 있는 모든 데이터의 조합, CARTESIAN PRODUCT

순수 관계 연산자

  • SELECT 연산WHERE 절로
  • PROJECT 연산SELECT 절로
  • (NATURAL) JOIN 연산은 다양한 JOIN 기능으로
  • DIVIDE 연산은 현재 사용 X

SELECT : SQL 문장에서는 WHERE 절의 조건절 기능으로 구현
PROJECT : SQL 문장에서는 SELECT 절의 컬럼 선택 기능으로 구현
JOIN : WHERE절의 INNER JOIN 조건과 함께 NATURAL JOIN, INNER JOIN, OUTER JOIN, USING 조건절, ON 조건절 등으로 발전
DIVIDE : 왼쪽 집합을 'XZ'로 나누었을 때, 즉 'XZ'를 모두 갖고 있는 a가 답이 되는 기능, 현재 사용 X

정규화 과정데이터 정합성데이터 저장 공간 절약을 위해 엔터티 분리


4. 테이블

누가 키가 제일 큰지, 누가 몸무게가 제일 많이 나가는지 판단하기 위해 엑셀처럼 키는 키대로, 몸무게는 몸무게대로 순서를 정해 비교하는 것이 바람직하다.

데이터관계형 데이터베이스의 기본 단위인 테이블(TABLE) 형태로 저장

모든 자료는 테이블에 등록되고, 테이블로부터 원하는 자료를 꺼내 옴

테이블은 반드시 하나 이상의 칼럼을 가져야 함

테이블 : 데이터를 저장하는 객체, 관계형 데이터베이스의 기본 단위
=> 관계형 데이터베이스에서는 모든 데이터칼럼이라는 2차원 구조로 나타냄
칼럼 : 세로 방향
: 가로 방향
필드 : 칼럼겹치는 하나의 공간

정규화를 통해 데이터의 불필요한 중복을 제거하여, 선수 테이블팀 테이블로 나누어 저장
=> 정규화데이터의 정합성 확보와 입력,수정,삭제 시 이상현상 방지


5. ERD

ERD : 테이블 간 서로의 상관관계를 그림으로 도식화한 것
=> 엔터티, 관계, 속성으로 구성

  • 하나의 팀은 여러 명의 선수를 포함할 수 있음
  • 한 명의 선수는 하나의 팀에 꼭 속함
  • 하나의 팀은 하나의 전용 구장을 꼭 가짐
  • 하나의 운동장은 하나의 홈팀을 가질 수 있음
  • 하나의 운동장은 여러 게임의 스케줄을 가질 수 있음
  • 하나의 스케줄은 하나의 운동장에 꼭 배정

  • 하나의 부서는 여러 명의 사원을 보유할 수 있음
  • 한 명의 사원은 하나의 부서에 꼭 소속됨

6. 데이터 유형

데이터 유형 : 데이터베이스의 테이블에 특정 자료를 입력할 때, 그 자료를 받아들일 공간을 자료의 유형별로 나누는 기준
지정한 크기 : 선언 당시에 지정한 데이터의 크기를 넘어선 자료가 입력시 에러 발생

varchar

  • 가변 길이
  • 필요한 영역은 실제 데이터 크기
  • 길이가 다양한 칼럼, 정의된 길이와 실제 데이터 길이에 차이가 있는 컬럼에 적합
  • 저장 측면에서 char보다 작은 영역에 저장 가능
  • 맨 처음부터 한 문자씩 비교하고, 공백하나의 문자로 취급하므로 끝의 공백이 다르면 다른 문자로 판단

char

  • 문자열 비교공백을 채워서 비교
    => 짧은 쪽 끝에 공백을 추가해 2개의 데이터가 같은 길이가 되도록 한 후, 앞에서부터 한 문자씩 비교
  • 끝의 공백다른 문자열같다고 판단
) CHAR 유형'AA' = 'AA ') VARCHAR 유형 'AA''AA '


🧈SELECT 문

1. SELECT

select : 사용자가 입력한 데이터를 조회

select [all/distinct] 출력 대상 칼럼명, 출력 대상 칼럼명, ...
from 출력 대상 컬럼이 있는 테이블명;
  • all : Default 옵션, 중복된 데이터가 있어도 모두 출력
  • distinct : 중복된 데이터가 있을 경우 1건으로 처리

SELECT PLAYER_ID, PLAYER_NAME, TEAM_ID, POSITION, HEIGHT, WEIGHT, BACK_NO
FROM PLAYER;

DISTINCT 옵션

select all position
from player;

-- all은 생략 가능한 키워드이므로 위와 같은 결과 출력
select position
from player;

select distinct position
from player;

null까지 총 5건의 데이터만 출력됨

애스터리스크(*) 사용하기

애스터리스크(*) : 해당 테이블의 모든 칼럼의 정보를 보고 싶을 경우 사용

select *
from 테이블명;

select *
from emp;

칼럼 레이블(LABLE)은 기본적으로 대문자로 보인다.

레이블의 정렬

  • 좌측 정렬 : 문자날짜 데이터
  • 우측 정렬 : 숫자 데이터

ALIAS 부여하기

칼럼 별명(ALIAS)

  • 칼럼명 바로 뒤에 옴
  • 칼럼명과 alias 사이 as 키워드를 사용 가능 (옵션)
  • 이중 인용부호(")는 alias가 공백, 특수문자를 포함할 경우, 대소문자 구분이 필요할 경우 사용
SELECT PLAYER_NAME AS 선수명, POSITION AS 위치, HEIGHT AS, WEIGHT AS 몸무게 
FROM PLAYER;

--as는 생략 가능하므로 위와 같음
SELECT PLAYER_NAME 선수명, POSITION 위치, HEIGHT 키, WEIGHT 몸무게
FROM PLAYER;

SELECT PLAYER_NAME "선수 이름", POSITION "그라운드 포지션", HEIGHT "키", WEIGHT "몸무게"
FROM PLAYER;


2. 산술 연산자와 합성 연산자

산술 연산자

numberdate 자료형에 대해 적용

우선순위 : (), *, /, +, -

SELECT PLAYER_NAME 이름, HEIGHT - WEIGHT "키-몸무게" 
FROM PLAYER;

합성 연산자

합성(CONCATENATION) 연산자 : 문자문자를 연결

  • 2개의 수직 바(||) 사용 (oracle)
  • + 사용 (SQL Server)
  • CONCAT (string1, string2) 함수 사용 (oracle, SQL Server)
  • 칼럼문자 또는 다른 칼럼과 연결
  • 문자 표현식의 결과에 의해 새로운 칼럼 생성
--Oracle 
SELECT PLAYER_NAME || '선수,' || HEIGHT || 'cm,' || WEIGHT || 'kg' 체격정보 
FROM PLAYER;

--SQL Server
SELECT PLAYER_NAME +'선수, '+ HEIGHT +'cm, '+ WEIGHT +'kg'체격정보
FROM PLAYER;



🍞함수

1. 내장 함수 개요

함수(Function)은 벤더에서 제공하는 함수인 내장 함수(Built-in Function)사용자가 정의할 수 있는 함수(User Defined Function)으로 나뉨

내장 함수 : SQL을 더 강력하게 해주고, 데이터 값을 간편하게 조작하는 데 사용

  • 단일행 함수(Single-Row) : 함수 입력 값단일행 값이 입력
  • 다중행 함수(Multi-Row) : 여러 행의 값이 입력
    => 집계함수(Aggregate), 그룹 함수(Group), 윈도우 함수(Window)로 나뉨

함수는 입력되는 값이 아무리 많아도 출력은 하나

단일행 함수는 단일행 내에 있는 하나의 값 또는 여러 값입력 인수로 표현
다중행 함수여러 레코드의 값들을 입력 인수로 사용

단일행 함수의 특징

  • select, where, order by절에 사용 가능
  • 각 행들에 대해 개별적으로 작용해 데이터 값들을 조작하고, 각각의 행에 대한 조작 결과 리턴
  • 여러 인자를 입력해도, 단 하나의 결과만 리턴
  • 함수의 인자로 상수, 변수, 표현식이 사용 가능하고, 하나의 인수를 가질 수 있지만 여러 개의 인수를 가질 수도 있음
  • 함수의 인자로 함수를 사용하는 함수의 중첩 가능

2. 문자형 함수

문자형 함수 : 문자 데이터를 매개 변수로 받아들여 문자숫자 값을 리턴

--oracle
SELECT LENGTH('SQL Expert') FROM DUAL;

--sql server
SELECT LEN('SQL Expert') AS ColumnLength; 

oracleselect절from절 두 개의 절을 select문장필수 절로 지정해 dual 테이블 필요

DUAL 테이블

  • 사용자 sys가 소유하며 모든 사용자가 액세스 가능
  • select~from~의 형식을 갖추기 위한 일종의 dummy 테이블
  • dummy라는 문자열 유형 컬럼에 'X'라는 값이 들어 있는 행 1건 포함
desc dual;

select * from dual;

SybaseSQL Serverselect절만으로도 sql문장 수행 가능

SELECT CONCAT(PLAYER_NAME, ' 축구선수') 선수명 FROM PLAYER; 

--oracle
SELECT PLAYER_NAME || ' 축구선수' AS 선수명 FROM PLAYER;

--sql server
SQL Server SELECT PLAYER_NAME + ' 축구선수' AS 선수명 FROM PLAYER;

--oracle
SELECT STADIUM_ID, DDD|| ')' || TEL as TEL, LENGTH(DDD||'-'||TEL) as T_LEN FROM STADIUM;

--sql server
SELECT STADIUM_ID, DDD+')'+TEL a s TEL, LEN(DDD+'-'+TEL) as T_LEN FROM STADIUM;


3. 숫자형 함수

숫자형 함수 : 숫자 데이터를 입력받아 처리 후 숫자 리턴

SELECT ENAME, ROUND(SAL/12,1), TRUNC(SAL/12,1) FROM EMP;

SELECT ENAME, ROUND(SAL/12), CEIL(SAL/12) FROM EMP;


4. 날짜형 함수

날짜형 함수 : DATE 타입의 값을 연산

데이터베이스는 날짜를 저장할 때, 세기/연/월/일/시/분/초와 같은 숫자 형식으로 변환해 저장
=> 숫자로 저장하기 때문에 산술 연산자로 계산 가능

SYSDATE + 10/(24*60*60)

  • SYSDATE : 2021/07/07 22:21:26
  • 결과 : 2021/07/07 22:21:36
  • 1/24 : 1일24로 나눔 (1시간)
  • 1/24/60/6 : 10초
--oracle
SELECT SYSDATE FROM DUAL; 

--sql server
SELECT GETDATE() AS CURRENTTIME;

--oracle
SELECT ENAME, HIREDATE,
EXTRACT(YEAR FROM HIREDATE) 입사년도,
EXTRACT(MONTH FROM HIREDATE) 입사월,
EXTRACT(DAY FROM HIREDATE) 입사일
FROM EMP;
 
SELECT ENAME, HIREDATE,
TO_NUMBER(TO_CHAR(HIREDATE,'YYYY')) 입사년도,
TO_NUMBER(TO_CHAR(HIREDATE,'MM')) 입사월,
TO_NUMBER(TO_CHAR(HIREDATE,'DD')) 입사일
FROM EMP;


--sql server
SELECT ENAME, HIREDATE,
DATEPART(YEAR, HIREDATE) 입사년도,
DATEPART(MONTH, HIREDATE) 입사월,
DATEPART(DAY, HIREDATE) 입사일
FROM EMP;

SELECT ENAME, HIREDATE,
YEAR(HIREDATE) 입사년도,
MONTH(HIREDATE) 입사월,
DAY(HIREDATE) 입사일
FROM EMP;


5. 변환형 함수

변환형 함수 : 특정 데이터 타입을 다양한 형식으로 출력하고자 할 경우 사용

암시적 데이터 유형 변환의 경우 성능 저하가 발생할 수 있다.

--oracle
SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD') 날짜,
TO_CHAR(SYSDATE, 'YYYY. MON, DAY') 문자형
FROM DUAL; 


--sql server
CONVERT(VARCHAR(10),GETDATE(),111) AS CURRENTDATE CURRNETDATE;
-- 2024-04-20 으로 출력됨
-- convert 함수의 111은 날짜 형식을 'yyyy/mm/dd'로 지정

SELECT TO_CHAR(123456789/1200,'$999,999,999.99') 환율반영달러,
TO_CHAR(123456789,'L999,999,999') 원화 --L은 로컬 화폐 단위
FROM DUAL;

--oracle
SELECT TEAM_ID, TO_NUMBER(ZIP_CODE1,'999') + TO_NUMBER(ZIP_CODE2,'999') 우편번호합
FROM TEAM;


--sql server
SELECT TEAM_ID, CAST(ZIP_CODE1 AS INT) + CAST(ZIP_CODE2 AS INT) 우편번호합 
FROM TEAM;


6. CASE 표현

CASE 표현 : IF-THEN-ELSE와 유사 (= oracle의 DECODE 함수)

--PL/SQL 로직
IF SAL > 2000
THEN REVISED_SALARY = SAL
ELSE REVISED_SALARY = 2000

END IF

--case 표현
SELECT ENAME,
	CASE WHEN SAL > 2000 THEN SAL ELSE 2000 END REVISED_SALARY
FROM EMP;

Simple Case Expression

case 조건 열
when 조건 값 then 무엇1
...
end

--oracle decode와 기능 동일
SELECT LOC,
	CASE LOC WHEN 'NEW YORK' THEN 'EAST'
    WHEN 'BOSTON' THEN 'EAST'
    WHEN 'CHICAGO' THEN 'CENTER'
    WHEN 'DALLAS' THEN 'CENTER'
    ELSE 'ETC'
    END as AREA
FROM DEPT;

Searched Case Expression

case when 조건열=조건값 then 무엇
...
end

-- equi 조건 외에도 여러 조건을 이용한 조건절 사용 가능
SELECT ENAME,
	CASE WHEN SAL >= 3000 THEN 'HIGH'
    WHEN SAL >= 1000 THEN 'MID'
    ELSE 'LOW'
    END AS SALARY_GRADE
FROM EMP;

--중첩 가능

SELECT ENAME, SAL,
	CASE WHEN SAL >= 2000 THEN 1000
    ELSE (CASE WHEN SAL >= 1000 THEN 500 ELSE 0 END)
    END as BONUS
FROM EMP;


7. NULL 관련 함수

NVL/ISNULL 함수

결과값을 null이 아닌 다른 값을 얻고자 할 때 사용.

null값의 대상이 숫자 유형이면 주로 0, 문자 유형이면 x로 주로 바꿈

--oracle
NVL(NULL 판단 대상, 'NULL일 때 대체값')

--sql server
ISNULL(NULL 판단 대상, 'NULL일 때 대체값')



--oracle
SELECT NVL(NULL, 'NVL-OK') NVL_TEST FROM DUAL;

--sql server
SELECT ISNULL(NULL, 'NVL-OK') ISNULL_TEST ;

--oracle
SELECT NVL('Not-Null', 'NVL-OK') NVL_TEST FROM DUAL;

--sql server
SELECT ISNULL('Not-Null', 'NVL-OK') ISNULL_TEST;

--oracle
SELECT PLAYER_NAME 선수명, POSITION, NVL(POSITION,'없음') 포지션
FROM PLAYER
WHERE TEAM_ID = 'K08';

--sql server
SELECT PLAYER_NAME 선수명, POSITION, ISNULL(POSITION,'없음') 포지션
FROM PLAYER
WHERE TEAM_ID = 'K08';


--case로 표현 가능
SELECT PLAYER_NAME 선수명, POSITION,
	CASE WHEN POSITION IS NULL THEN '없음' ELSE POSITION END AS 포지션
FROM PLAYER
WHERE TEAM_ID = 'K08';

NVL2 함수

--oracle
NVL2(NULL 판단 대상, 'NULL이 아닐 때 대체값','NULL일 때 대체값');

-- 인수1이 null이면 인수3 반환, 인수1이 null이 아니면 인수2 반환

NULL과 공집합

-- 매니저가 NULL인 경우 빈칸이 아닌 9999로 출력하기 위해 NVL/ISNULL 사용
SELECT NVL(MGR,9999) MGR FROM EMP WHERE ENAME='KING';

공집합 : 조건에 맞는 데이터가 한 건도 없는 경우

select 1 from dual where 1=2;

공집합NULL 데이터와는 다르다

SELECT MGR FROM EMP WHERE ENAME='JSC';

인수의 값이 공집합인 경우, nvl/isnull 함수를 사용해도 공집합이 출력

SELECT NVL(MGR, 9999) MGR FROM EMP WHERE ENAME='JSC';

집계함수스칼라 서브쿼리는 인수의 결과 값이 공집합이라도 NULL 출력

SELECT MAX(MGR) MGR FROM EMP WHERE ENAME='JSC';

집계함수를 인수로 할 경우 nvl/isnull 함수 사용해서 9999로 출력 가능

SELECT NVL(MAX(MGR), 9999) MGR FROM EMP WHERE ENAME='JSC';

NULLIF

NULLIF(EXPR1, EXPR2)

NULLIF : EXPR1이 EXPR2와 같으면 NULL, 같지 않으면 EXPR1을 리턴

SELECT ENAME, EMPNO, MGR, NULLIF(MGR,7698) NUIF FROM EMP;

--case표현 가능
SELECT ENAME, EMPNO, MGR,
  CASE WHEN MGR = 7698 THEN NULL ELSE MGR
  END NUIF
FROM EMP;

기타 NULL 관련 함수(COALESCE)

COALESCE( EXPR1, EXPR2, ...)

COALESCE : 인수의 숫자 한정X, expr 중 null이 아닌 최초의 expr을 리턴, 모두 null이면 null 리턴

SELECT ENAME, COMM, SAL, COALESCE(COMM, SAL) COAL FROM EMP;

--case 표현 가능
SELECT ENAME, COMM, SAL,
  CASE WHEN COMM IS NOT NULL THEN COMM
  ELSE (CASE WHEN SAL IS NOT NULL THEN SAL ELSE NULL END)
  END COAL
FROM EMP;



🥐WHERE 절

1. WHERE 조건절 개요

where : 두 개 이상의 테이블에 대한 조인 조건을 기술하거나, 결과 제한을 위한 조건 기술

select [distinct/all] 컬럼명 [alias 명]
from 테이블명
where 조건식;

where절 구성

  • 칼럼명
  • 비교 연산자
  • 문자, 숫자, 표현식
  • 비교 칼럼명(JOIN시)

2. 연산자의 종류

where절에 사용되는 연산자

  • 비교 연산자(부정 비교 연산자 포함)
  • SQL 연산자(부정 SQL 연산자 포함)
  • 논리 연산자

  • 괄호로 묶은 연산이 제일 먼저 처리
  • 연산자들 중 비교 연산자, SQL 연산자 처리
  • 부정 연산자 처리
  • 논리 연산자 중 and, or 순서대로 처리

3. 비교 연산자

비교 연산자칼럼들을 특정한 값들과 조건을 비교하는 데 사용

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'K02' ;

숫자 유형의 칼럼의 경우, 숫자로 변환 가능한 문자열과 비교시 상대 타입을 숫자 타입으로 변경해 비교

where height>='170'

이라고 표현시, '170'170으로 변경되어 처리


4. SQL 연산자

IN (list) 연산자

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID IN ('K02','K07');

다중 리스트를 이용한 IN 연산자는 성능 측면에서도 장점이 있어 적극 사용 권고

SELECT ENAME, JOB, DEPTNO
FROM EMP
WHERE (JOB, DEPTNO) IN (('MANAGER',20),('CLERK',30));

-- 아래와 다름
SELECT ENAME, JOB, DEPTNO
FROM EMP
WHERE JOB IN ('MANAGER','CLERK')
AND DEPTNO IN (20,30);

LIKE 연산자

와일드카드(WildCard) : 한 개 혹은 0개 이상의 문자를 대신해 사용하기 위한 특수문자

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE PLAYER_NAME LIKE '장%';

BETWEEN a AND b 연산자

BETWEEN a AND b : 범위에서 ab의 값을 포함

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE HEIGHT BETWEEN 170 AND 180;

IS NULL 연산자

null값과의 비교 연산거짓(FALSE)를 리턴

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE POSITION = NULL;
-- where 조건절이 false가 되어 만족하는 레코드가 하나도 안나오는 공집합

SELECT PLAYER_NAME 선수이름, POSITION 포지션, TEAM_ID
FROM PLAYER
WHERE POSITION IS NULL;


5. 논리 연산자

논리 연산자 : 비교 연산자나 SQL 연산자들로 이루어진 여러 개의 조건들을 논리적으로 연결시키기 위해 사용

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID IN ('K02','K07') AND POSITION = 'MF';


6. 부정 연산자

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'K02'
AND NOT POSITION = 'MF'
AND NOT HEIGHT BETWEEN 175 AND 185;

--위와 동일
SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'K02'
AND POSITION <> 'MF'
AND HEIGHT NOT BETWEEN 175 AND 185;

SELECT PLAYER_NAME 선수이름, NATION 국적
FROM PLAYER
WHERE NATION IS NOT NULL;



🥨GROUP BY, HAVING 절

1. 집계함수

집계함수(Aggregate Function)

  • 여러 행들의 그룹이 모여 그룹당 단 하나의 결과를 돌려주는 함수
  • GROUP BY절들을 소그룹화
  • SELECT절, HAVING절, ORDER BY절에 사용 가능
집계함수명 ([distinct|all] 칼럼이나 표현식)
  • all : default옵션으로, 생략 가능
  • distinct : 같은 값을 하나의 데이터로 간주시 사용

SELECT COUNT(*) "전체 행수", COUNT(HEIGHT) "키 건수",
	MAX(HEIGHT) 최대키, MIN(HEIGHT) 최소키, ROUND(AVG(HEIGHT),2) 평균키
FROM PLAYER;

count(*)는 전체 행의 개수를 출력
count(height)null값이 아닌 건수만 출력


2. GROUP BY 절

group by : 데이터들을 작은 그룹으로 분류해 소그룹에 대한 항목별 통계 정보 얻을 때 사용

select [distinct] 칼럼명 [alias명]
from 테이블명
[where 조건식]
[group by 칼럼(Column)이나 표현식]
[having 그룹조건식];

group by 절having 절 특성

  • group by절을 통해 소그룹별 기준을 정한 후, select절에 집계함수 사용
  • 집계함수의 통계 정보는 null값 제외
  • group by절에는 alias 명 사용 X
  • 집계함수는 where절에 올 수 없음
    => 집계함수 사용 group by절보다 where절이 먼저 수행되므로
  • where절은 전체 데이터를 group으로 나누기 전 행 제거
  • having절은 group by절의 기준 항목이나 소그룹의 집계함수를 이용한 조건 표시 가능
  • group by절에 의한 소그룹별로 만들어진 집계 데이터 중, having절에 제한 조건을 두어 조건 만족하는 내용만 출력
  • having절은 일반적으로 group by절 뒤에 위치
SELECT POSITION 포지션, AVG(HEIGHT) 평균키 FROM PLAYER;

group by절에 그룹 단위를 표시해주어야 select절에서 그룹 단위 칼럼집계함수 사용 가능

SELECT POSITION 포지션, COUNT(*) 인원수, COUNT(HEIGHT) 키대상,
	MAX(HEIGHT) 최대키, MIN(HEIGHT) 최소키, ROUND(AVG(HEIGHT),2) 평균키
FROM PLAYER
GROUP BY POSITION;

포지션키 정보가 없는 선수가 3명이라는 정보를 얻을 수 있다.


3. HAVING 절

HAVING : 그룹을 나타내는 결과 집합의 행에 조건 적용

SELECT POSITION 포지션, ROUND(AVG(HEIGHT),2) 평균키
FROM PLAYER
GROUP BY POSITION
HAVING AVG(HEIGHT) >= 180;

group by절과 having절 순서를 바꾸어도 에러가 없다 (sql server는 문법오류)

SELECT POSITION 포지션, ROUND(AVG(HEIGHT),2) 평균키
FROM PLAYER
GROUP BY POSITION
HAVING MAX(HEIGHT) >= 190;

having절select절에 사용되지 않은 컬럼이나 집계함수라도, group by절의 기준 항목이나 소그룹의 집계함수를 이용한 조건 표시 가능


4. CASE 표현을 활용한 월별 데이터 집계

집계함수(case())~group by : 반복되는 칼럼의 경우 구분 칼럼을 두어, 여러 개의 레코드로 만들어진 집합을 정해진 칼럼 수만큼 확장해 집계 보고서를 만드는 유용한 기능

--개별 데이터 확인
--월별 데이터 추출

SELECT ENAME, DEPTNO, EXTRACT(MONTH FROM HIREDATE) 입사월, SAL FROM EMP;

-- 월별 데이터 구분
SELECT ENAME, DEPTNO,
  CASE MONTH WHEN 1 THEN SAL END M01,
  CASE MONTH WHEN 2 THEN SAL END M02,
  CASE MONTH WHEN 3 THEN SAL END M03,
  CASE MONTH WHEN 4 THEN SAL END M04,
  CASE MONTH WHEN 5 THEN SAL END M05,
  CASE MONTH WHEN 6 THEN SAL END M06,
  CASE MONTH WHEN 7 THEN SAL END M07,
  CASE MONTH WHEN 8 THEN SAL END M08,
  CASE MONTH WHEN 9 THEN SAL END M09,
  CASE MONTH WHEN 10 THEN SAL END M10,
  CASE MONTH WHEN 11 THEN SAL END M11,
  CASE MONTH WHEN 12 THEN SAL END M12
FROM (SELECT ENAME, DEPTNO, EXTRACT(MONTH FROM HIREDATE) MONTH, SAL
	FROM EMP);

--부서별 데이터 집계
SELECT DEPTNO,
  AVG(CASE MONTH WHEN 1 THEN SAL END) M01,
  AVG(CASE MONTH WHEN 2 THEN SAL END) M02,
  AVG(CASE MONTH WHEN 3 THEN SAL END) M03,
  AVG(CASE MONTH WHEN 4 THEN SAL END) M04,
  AVG(CASE MONTH WHEN 5 THEN SAL END) M05,
  AVG(CASE MONTH WHEN 6 THEN SAL END) M06,
  AVG(CASE MONTH WHEN 7 THEN SAL END) M07,
  AVG(CASE MONTH WHEN 8 THEN SAL END) M08,
  AVG(CASE MONTH WHEN 9 THEN SAL END) M09,
  AVG(CASE MONTH WHEN 10 THEN SAL END) M10,
  AVG(CASE MONTH WHEN 11 THEN SAL END) M11,
  AVG(CASE MONTH WHEN 12 THEN SAL END) M12
FROM (SELECT ENAME, DEPTNO, EXTRACT(MONTH FROM HIREDATE) MONTH, SAL
	FROM EMP)
GROUP BY DEPTNO ;

하나의 SQL 문장으로 리포트를 작성할 수 있어 처리 속도나 자원 활용 측면에서 효율적


5. 집계함수와 NULL 처리

다중행 함수를 사용하는 경우, nvl함수다중행 함수 안에 사용할 필요 X(부하 발생)

다중행 함수전체 건수null값인 경우만 함수 결과가 null이 나오고, 일부만 null인 경우 null인 행을 다중 행 함수 대상에서 제외

case표현에서 else 생략시, default값null
decode함수에서 4번째 인자 생략시 null이 default

불필요하게 else절에 0을 지정하면, sum연산에 0이 포함되므로 같은 결과를 얻는다면 가능한 else절상수값을 지정하지 않거나 생략하도록 함

SELECT TEAM_ID,
  NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 ELSE 0 END),0) FW,
  NVL(SUM(CASE POSITION WHEN 'MF' THEN 1 ELSE 0 END),0) MF,
  NVL(SUM(CASE POSITION WHEN 'DF' THEN 1 ELSE 0 END),0) DF,
  NVL(SUM(CASE POSITION WHEN 'GK' THEN 1 ELSE 0 END),0) GK,
  COUNT(*) SUM
FROM PLAYER
GROUP BY TEAM_ID;

sum(nvl(sal,0)) 또는 sum(isnull(sal,0) 에서 급여가 null인 경우 자연스럽게 sum연산에서 빠지므로 불필요하게 nvl 함수를 사용하지 않아도 된다. nvl(sum(sal),0)으로 사용하면 된다.

SELECT TEAM_ID,
  NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 END),0) FW,
  NVL(SUM(CASE POSITION WHEN 'MF' THEN 1 END),0) MF,
  NVL(SUM(CASE POSITION WHEN 'DF' THEN 1 END),0) DF,
  NVL(SUM(CASE POSITION WHEN 'GK' THEN 1 END),0) GK,
  COUNT(*) SUM
FROM PLAYER
GROUP BY TEAM_ID;



🥯ORDER BY 절

1. ORDER BY 정렬

ORDER BY : 특정 칼럼을 기준으로 정렬에 사용
=> 칼럼명 대신 alias명이나 칼럼 순서를 나타내는 정수 사용 가능
=> 기본적으로 오름차순

select 칼럼명 [alias명]
from 테이블명
[where 조건식]
[group by 칼럼이나 표현식]
[having 그룹조건식]
[order by 칼럼이나 표현식 [asc 또는 desc]];

order by절정렬 방식

  • ASC(Ascending) : 조회한 데이터를 오름차순 정렬 (기본값, 생략가능)
  • DESC(Descending) : 조회한 데이터를 내림차순 정렬
SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버
FROM PLAYER
ORDER BY 포지션 DESC;

NULL 정렬

  • oracle : NULL값가장 큰 값 취급
  • sql server : NULL값가장 작은 값 취급

order by절특징

  • 기본적인 정렬 순서는 오름차순(asc)
  • 숫자형 데이터 타입은 오름차순시 가장 작은 값부터 출력
  • 날짜형 데이터 타입은 오름차순시 가장 빠른 값부터 출력
    => ex. 01-JAN-2012가 01-SEP-2012보다 먼저 출력
  • oraclenull값을 가장 값으로 간주해 오름차순마지막, 내림차순시 가장 먼저
  • sql servernull값을 가장 작은 값으로 간주해 오름차순먼저, 내림차순시 가장 마지막
  • 칼럼명, alias명, 칼럼 순서를 같이 혼용 가능
SELECT DNAME, LOC AREA, DEPTNO
FROM DEPT
ORDER BY 1, AREA, 3 DESC;


2. SELECT 문장 실행 순서

select 칼럼명 [alias명]--5
from 테이블명			--1
where 조건식			--2
group by 칼럼이나 표현식	--3
having 그룹조건식		--4
order by 칼럼이나 표현식;--6

order by 절에는 select 목록에 나타나지 않은 문자형 항목이 포함 가능
=> distinct 지정, group by 존재, union연산자 존재 시 불가능
=> 관계형 DB가 데이터를 메모리에 올릴 때 행 단위모든 칼럼을 가져오므로 가능

--select절에 없는 mgr 컬럼으로 정렬 가능

SELECT EMPNO, ENAME FROM EMP ORDER BY MGR;

SELECT MGR
FROM (SELECT EMPNO, ENAME FROM EMP ORDER BY MGR);

서브쿼리select절에서 선택되지 않은 칼럼들은 범위를 벗어나면 더이상 사용 불가

group by 사용시, 그룹핑 기준에 사용된 칼럼집계함수에 사용될 수 있는 숫자형 데이터 칼럼으로 집합을 새로 만듦, 개별 데이터는 필요 없으므로 저장X
=> group by 이후 select절이나 order by절에서 개별 데이터 사용시 에러

SELECT JOB, SAL --select절에 일반 칼럼
FROM EMP
GROUP BY JOB
HAVING COUNT(*) > 0
ORDER BY SAL;

SELECT JOB
FROM EMP
GROUP BY JOB
HAVING COUNT(*) > 0
ORDER BY SAL;  --order by 절에 일반 칼럼

-- order by 절에 집계 칼럼 사용
select job, sum(sal) as salary_sum
from emp
group by job
having sum(sal)>5000
order by sum(sal);



🥖조인

1. 조인 개요

조인(JOIN) : 두 개 이상의 테이블들을 연결해 데이터를 출력

FROM절에 여러 테이블이 나열되더라도 SQL에서 데이터 처리시 단 두개의 집합 간에만 조인 발생
=>ex. A,B,C,D 조인시 (((A join D) join C) join B)와 같이 순차적으로 조인 처리


2. EQUI JOIN

EQUI JOIN : 두 개의 테이블 간에 칼럼 값들이 정확하게 일치하는 경우 사용

SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...
FROM 테이블1, 테이블2
WHERE 테이블1.칼럼명1 = 테이블2.칼럼명2; --where절에 join 조건 기술, "=" 사용

--ansi/iso 표준
SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...
FROM 테이블1 INNER JOIN 테이블2 
ON 테이블1.칼럼명1 = 테이블2.칼럼명2; --on 절에 join 조건 기술 
SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명
FROM PLAYER, TEAM
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID; 

inner join에 참여하는 테이블이 n개일 경우, 필요한 조인 조건은 n-1개 이상이 필요

선수-팀 EQUI JOIN 사례

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, PLAYER.TEAM_ID, TEAM.TEAM_NAME, TEAM.REGION_NAME
FROM PLAYER, TEAM
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;

선수-팀 WHERE절 검색 조건 사례

where절에 추가적인 제한 조건 입력 가능

SELECT P.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID AND P.POSITION = 'GK'
ORDER BY P.BACK_NO; 

테이블에 대한 alias 적용해 sql 작성시 where절select절에는 테이블명이 아닌 alias를 사용해야 함

팀-경기장 EQUI 조인 사례

SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEAT_COUNT
FROM TEAM T, STADIUM S
WHERE T.STADIUM_ID = S.STADIUM_ID;


3. Non EQUI JOIN

Non EQUI JOIN : 두 개 테이블 간 논리적인 연관 관계를 가지나, 칼럼 값들이 서로 일치하지 않는 경우 사용
=> =가 아닌 Between, >, >=, <, <= 등의 연산자들을 사용해 JOIN 수행

SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...
FROM 테이블1, 테이블2
WHERE 테이블1.칼럼명1 BETWEEN 테이블2.칼럼명1 AND 테이블2.칼럼명2;

사원이 받고 있는 급여가 어느 등급에 속하는지 알기 위해 급여등급 테이블을 생성하자

create table SALGRADE(
    GRADE number,
    LOSAL number,
    HISAL number);
    
insert into salgrade values(1,700,1200);
insert into salgrade values(2,1201,1400);
insert into salgrade values(3,1401,2000);
insert into salgrade values(4,2001,3000);
insert into salgrade values(5,3001,9999);

SELECT E.ENAME 사원명, E.SAL 급여, S.GRADE 급여등급
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;


4. 3개 이상 TABLE JOIN

선수 테이블과 운동장 테이블은 서로 관계가 없어 세 개의 테이블을 조인해야만 원하는 데이터를 얻을 수 있음

SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지, T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P, TEAM T, STADIUM S 
WHERE P.TEAM_ID = T.TEAM_ID AND T.STADIUM_ID = S.STADIUM_ID
ORDER BY 선수명;


5. OUTER JOIN

OUTER JOIN : 조인 조건을 만족하지 않는 행들도 함께 반환

select 테이블1.칼럼명, 테이블2. 칼럼명, ...
from 테이블1, 테이블2
where 테이블2.칼럼명(+) = 테이블1.칼럼명;

oracle의 (+)

  • (+) 표시의 반대편에 있는 테이블이 outer join기준 테이블
  • 기준 테이블의 모든 데이터 표시

조인에 실패한 행들의 경우 기준 테이블은 칼럼들의 이 표시되고, 그 외 테이블에서 가져오는 칼럼들은 null로 표시

--홈팀이 없는 경기장도 출력
SELECT STADIUM_NAME, A.STADIUM_ID, SEAT_COUNT, HOMETEAM_ID, TEAM_NAME
FROM STADIUM A, TEAM B
WHERE B.TEAM_ID(+) = A.HOMETEAM_ID
ORDER BY A.HOMETEAM_ID;



🧀표준 조인

1. FROM 절 조인 형태

from절조인 형태

  • inner join
  • natural join
  • using 조건절
  • on 조건절
  • cross join
  • outer join

ON조건절의 경우 natural join 처럼 join조건이 숨어 있지 않고, 명시적으로 join 조건을 구분할 수 있으며, using조건절이나 natural join과 다르게 칼럼명이 다르더라도 join조건으로 사용 가능


2. INNER JOIN

INNER JOIN : 조인 조건을 만족하는 행들만 반환
=> USING 조건절이나 ON 조건절을 필수적으로 사용해야 함

--where절 조인 조건
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO; 


--from절 조인 조건
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP INNER JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO;


3. NATURAL JOIN

NATURAL JOIN : 두 테이블 간 동일한 이름을 갖는 모든 칼럼들에 대해 EQUI JOIN 수행
=> USING 조건절, ON 조건절, WHERE절에서 조인 조건 정의 X
=> SQL Server에서 지원X

SELECT A.DEPTNO, A.EMPNO, ENAME, B.DNAME
FROM EMP A NATURAL JOIN DEPT B;

두 테이블에서 deptno라는 공통된 칼럼을 자동으로 인식해 조인 처리

조인에 사용된 칼럼들은 같은 데이터 유형이어야 하며, alias테이블명과 같은 접두사 붙일 수 없음

데이터 성격(도메인)도 동일해야 함

-- 칼럼 순서 지정 X시 조인 기준 칼럼이 먼저 출력됨
-- 조인에 사용된 같은 이름의 칼럼을 하나로 처리

SELECT * FROM EMP NATURAL JOIN DEPT;

-- 첫번째 테이블, 두번째 테이블 순으로 데이터 출력
-- 조인에 사용된 컬럼은 별개로 표시

SELECT * FROM EMP INNER JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO;

natural joininner join의 차이를 자세히 알아보자

-- dept_temp 테이블 생성

--oracle
create table dept_temp
as select * from dept;

--sql server
select * into dept_temp from dept;


-- update
update dept_temp
set dname='CONSULTING'
where dname='RESEARCH';

update dept_temp
set dname='MARKETING'
where dname='SALES';
-- dept_temp 출력
select *
from dept_temp;

select *
from dept a
natural join dept_temp b;

세 개의 칼럼명이 모두 같아 위와 같이 출력되었으며, dname이 같지 않은 20, 30의 데이터는 제외

select *
from dept a join dept_temp b
on b.deptno=a.deptno
and b.dname=a.dname
and b.loc=a.loc;

같은 컬럼명이 2개씩 표현된 것을 확인할 수 있다.


4. USING 조건절

using 조건절 : 같은 이름을 가진 칼럼 중 원하는 칼럼만 선택적으로 EQUI 조인 가능
=> sql server 지원X

SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (DEPTNO);

칼럼 순서를 지정하지 않으면, using 조건절의 기준이 되는 칼럼이 다른 컬럼보다 먼저 출력

using 조건절은 조인에 사용된 칼럼을 하나로 처리

SELECT DEPTNO, DEPT.DNAME, DEPT.LOC, DEPT_TEMP.DNAME, DEPT_TEMP.LOC
FROM DEPT JOIN DEPT_TEMP USING (DEPTNO);

natural join과 마찬가지로 조인 칼럼에 대해서는 alias테이블명과 같은 접두사 X

SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (LOC, DEPTNO);

loc와 deptno가 순서대로 출력되며 조인 조건에 참여하지 않은 dname 칼럼은 2개의 칼럼으로 표시


5. ON 조건절

ON조건절where조건절에 비해 분리되어 이해하기 쉬우며, 컬럼명이 다르더라도 조인 조건으로 사용 가능

SELECT E.EMPNO, E.ENAME, E.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);

on조건절괄호는 옵션

from절테이블이 많이 사용될 경우 가독성이 떨어짐

WHERE 절과의 혼용

SELECT E.ENAME, E.DEPTNO, D.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE E.DEPTNO = 30;

ON 조건절 + 데이터 검증 조건 추가

on조건절데이터 검색 조건을 추가할 수 있으나, where절 사용 권고
=> 아우터 조인에서 조인 대상 제한을 위한 목적이면, on절에 표기

SELECT E.ENAME, E.MGR, D.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D ON (E.DEPTNO = D.DEPTNO AND E.MGR = 7698); 

ON 조건절 예제

SELECT TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID
ORDER BY STADIUM_ID;


--using 가능
SELECT TEAM_NAME, STADIUM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM
USING (STADIUM_ID)
ORDER BY STADIUM_ID; 

SELECT TEAM_NAME, TEAM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM ON TEAM.TEAM_ID = STADIUM.HOMETEAM_ID
ORDER BY TEAM_ID;

--다른 이름의 칼럼으로 조인하므로 using 조건절 사용 불가

다중 테이블 조인

-- 사원과 dept 테이블, dept_temp의 부서명 출력
SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME New_DNAME
FROM EMP E JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
	JOIN DEPT_TEMP T ON (E.DEPTNO = T.DEPTNO);

-- 홈팀이 3점 이상 차이로 승리한 경기
SELECT B.STADIUM_NAME, B.STADIUM_ID,
	A.SCHE_DATE, C.TEAM_NAME, D.TEAM_NAME, A.HOME_SCORE, A.AWAY_SCORE
FROM SCHEDULE A JOIN STADIUM B ON B.STADIUM_ID = A.STADIUM_ID
	JOIN TEAM C ON A.HOMETEAM_ID = C.TEAM_ID
    JOIN TEAM D ON A.AWAYTEAM_ID = D.TEAM_ID
WHERE A.HOME_SCORE > = A.AWAY_SCORE +3;


6. CROSS JOIN

CROSS JOIN : 테이블 간 조인 조건이 없는 경우 생길 수 있는 모든 데이터의 조합
=> M*N건의 데이터 조합 발생

SELECT ENAME, DNAME
FROM EMP CROSS JOIN DEPT
ORDER BY ENAME;

emp 테이블 14건 * dept 4건으로 56개 행 출력

SELECT ENAME, DNAME
FROM EMP CROSS JOIN DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO; 


--위와 결과 같음
SELECT ENAME, DNAME
FROM EMP INNER JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO;

cross join의 경우 where절에 조인 조건을 추가할 수 있는데, 이 경우 inner join과 같은 결과를 얻음


7. OUTER JOIN

(+)의 경우 where절의 검색 조건 구분이 불명확, in이나 or연산자 사용시 에러, 누락된 조인 및 검색 조건 존재 시 outer join이 아닌 inner join으로 수행, full outer join 미지원 등의 불편함 존재

outer join
=> using 조건절이나 on조건절 필수

LEFT OUTER JOIN

LEFT OUTER JOIN : 조인 수행 시 먼저 표기된 좌측 테이블에 해당하는 데이터를 먼저 읽은 후, 나중 표기된 우측 테이블에서 조인 대상 데이터를 읽어 옴
=> 조인 조건 만족하는 값 X시 우측 테이블 칼럼은 NULL값으로 채움

--홈팀이 없는 경기장도 같이 출력
SELECT STADIUM_NAME, STADIUM.STADIUM_ID, SEAT_COUNT, HOMETEAM_ID, TEAM_NAME
FROM STADIUM LEFT OUTER JOIN TEAM ON STADIUM.HOMETEAM_ID = TEAM.TEAM_ID 
ORDER BY HOMETEAM_ID;

RIGHT OUTER JOIN

RIGHT OUTER JOIN : LEFT JOIN과 반대로 우측 테이블이 기준이 되어 결과 생성
=> OUTER 키워드 생략 가능

-- 사원이 없는 부서도 함께 출력
SELECT E.ENAME, D.DEPTNO, D.DNAME
FROM EMP E RIGHT OUTER JOIN DEPT D ON E.DEPTNO = D.DEPTNO;

FULL OUTER JOIN

FULL OUTER JOIN : 조인 수행 시 좌측, 우측 테이블의 모든 데이터를 읽어 조인해 결과 생성
=> RIGHT OUTER JOINLEFT OUTER JOIN의 결과를 합집합으로 처리한 결과와 동일
(조인 성공 행은 한번만 표시)
=> outer 키워드 생략 가능

-- full outer 사례 만들기 위해 update

UPDATE DEPT_TEMP SET DEPTNO = DEPTNO + 20; SELECT * FROM DEPT_TEMP;

SELECT *
FROM DEPT FULL OUTER JOIN DEPT_TEMP ON DEPT.DEPTNO = DEPT_TEMP.DEPTNO;


8. INNER vs. OUTER vs. CROSS JOIN 비교

inner join : 양쪽 테이블에 모두 존재하는 B-B, C-C 2건 출력
left outer join : tab1 기준으로 b-b, c-c, d-null, e-null 4건 출력
right outer join : tab2 기준으로 null-a, b-b, c-c 3건 출력
full outer join : 양쪽 기준으로 null-a, b-b, c-c, d-null, e-null 5건 출력
cross join : 조인 가능한 모든 경우의 수(outer join 제외)
=> b-a, b-b, b-c, c-a, c-b, c-c, d-a, d-b, d-c, e-a, e-b, e-c 총 12건 (4*3)

profile
MSSQL DBA 신입

0개의 댓글