관계형 데이터베이스

  • RDB(Relational Database)라고 불리는 관계형 데이터베이는 말 그대로 관계형 데이터 모델에 기초를 둔 데이터베이스이다.
  • 관계형 데이터베이스의 설계는 모든 데이터를 2차원 테이블 형태로 표현한 뒤 각 테이블 간의 관계를 정의하는 것으로 시작된다.
  • RDBMS(Relational Database Management System)는 이러한 RDB를 관리 감독하기 위한 시스템이다.
  • Ex. Oracle, SQL Server(MSSQL), MySQL, MariaDB, PostgreSQL 등

Table

  • 관계형 데이터베이스를 표현할때 사용하는 형식이다.(엑셀 표 형식과 유사)
  • 항목을 나타내는 각각의 세로 열을 칼럼(Column)이라고 한다.
  • 각각의 가로 행을 로우(Row)라고 한다.
  • 테이블은 관계형 데이터베이스의 기본 단위이고 일반적으로 데이터베이스는 여러 개의 테이블로 구성된다.
  • 데이터를 저장하는 주된 목적은 데이터를 활용하는 데에 있고 우리는 그것을 테이블 형태로 조회하고 변경하고 삭제할 수 있다.
게임 유저명 플레이타임(시간)
메이플 닉네임메 10
닉네임롤 20

 

SQL(Structured Query Language)

  • SQL은 관계형 데이터베이스에서 데이터를 다루기 위해 사용하는 언어이다.
  • 간단한 SQL 작성 방법은 뻔하기에 누가 작성하든 비슷하지만 라인 수가 많아지는 복잡한 SQL은 어떻게 작성하냐에 따라 성능 차가 확연하기에 SQL을 잘 작성하고 튜닝하는 것이 중요하다.

SELECT

  • 저장되어 있는 데이터를 조회하고자 할 때 사용하는 명령어이다.
SELECT 컬럼1, 컬럼2, ... FROM 테이블 WHERE 컬럼1 = '아무개';
  • 컬럼을 따로 명시하지 않고 *(asterisk)를 쓰면 전체 컬럼이 조회되며 조회되는 컬럼의 순서는 테이블 컬럼 순서와 동일하다.
SELECT * FROM 테이블;
  • 별도의 WHERE 절이 없으면 테이블 전체 Row가 조회된다.
SELECT BAND.BAND_NAME, BAND_MEMBER.MEMBER_NAME
FROM BAND, BAND_MEMBER
WHERE BAND.BAND_CODE = BAND_MEMBER.BAND_CODE;

SELECT B.BAND_NAME, BM.MEMBER_NAME
FROM BAND B, BAND_MEMBER BM
WHERE B.BAND_CODE = BM.BAND_CODE;
  • 테이블이나 컬럼 명에 별도의 별칭을(Alias)을 붙여줄 수 있는데, 붙여주는 목적은 줄여쓰기 위함이다.
  • FROM절에서 정의한다.
  • 테이블명에 Alias를 설정했을 경우 테이블명 대신 Alisa를 사용해야 한다. 아닐 경우 문법 에러가 발생한다.

산술 연산자

  • 수학에서 사용하는 사칙연산의 기능을 가진 연산자이다.
  •  NULL이 포함된 연산을 주의하자
    • 다른 컬럼끼리 연산(가로 연산)에서 NULL이 포함되어 있으면 결과 값은 NULL이다
    • 다른 로우끼리 연산(세로 연산)에서 NULL이 포함되어 있으면 결과 값은 NULL을 제외하고 연산한 결과이다.
연산자 의미 우선순위
() 우선순위 조정 1
* 곱하기 2
/ 나누기
+ 더하기 3
- 빼기

합성 연산자

  • 문자와 문자를 연결할 때 사용하는 연산자이다.
SELECT 'S'||'Q'||'L'||'개'||'발'||'자' AS SQLD FROM DUAL

SQLD
SQL개발자

 

함수

  • 데이터베이스에서 매핑을 제공하는 함수들이 있다.
  • 문자 함수
    • CHR(ASCII 코드)
      • ASCII 코드는 총 128개의 문자를 숫자로 표현할 수 있도록 정의해 놓은 코드이다.
      • ASCII 코드를 인수로 입력하였을때 매핑되는 문자가 무엇인지를 알려주는 함수이다.
      • Ex. CHR(65) → A
    • LOWER(문자열)
      • 문자열을 소문자로 변환해주는 함수이다.
      • Ex. LOWER('KIM') → kim
    • UPPER(문자열)
      • 문자열을 대문자로 변환해주는 함수이다.
    • LTRIM(문자열 [,특정 문자]) *[]는 옵션
      • 특정 문자를 따로 명시해주지 않으면 문자열의 왼쪽 공백을 제거한다.
      • 특정 문자를 명시한 경우 문자열을 왼쪽부터 한 글자씩 특정 문자와 비교하여 특정 문자에 포함되어 있으면 제거하고 포함되지 않았으면 멈춘다.
      • 문자 사이의 공백은 제거하지 않는다.
      • SQL Server(MSSQL)의 경우 공백 제거만 가능하다.
      • Ex. LTRIM('    KIM') → KIM
      • Ex. LTRIM('DATABASE', 'DE') → ATABASE
    • RTLIM(문자열 [,특정 문자]) *[]는 옵션
      • LTRIM과 방향만 반대이고 같은 기능을 가진다.
    • TRIM([위치] [특정 문자] [FROM] 문자열) *[]는 옵션
      • 옵션이 없는 경우 문자열 양쪽의 공백을 제거한다.
      • 옵션이 있는 경우 옵션에 따라 지정된 위치에서 한 글자씩 특정 문자와 비교하여 제거하고 다르면 멈춘다.
      • SQL Server(MSSQL)의 경우 공백 제거만 가능하다.
      • Ex. TRIM('   KIM   ') → KIM
      • Ex. TRIM(LEADING 'K' FROM 'KIM') → IM
      • Ex. TRIM(TRALLING 'M' FROM 'KIM') → KI
    • SUBSTR(문자열, 시작점 [,길이]) *[]는 옵션
      • 문자열의 원하는 부분만 잘라서 반환해주는 함수이다.
      • 길이를 명시하지 않은 경우 문자열의 시작부터 끝까지 반환된다.
      • 길이 옵션보다 문자열이 짧은 경우 문자열의 끝까지 반환된다.
      • Ex. SUBSTR('교촌치킨허니콤보', 3, 2) → 치킨
      • Ex. SUBSTR('교촌치킨허니콤보', 5, 4) → 허니콤보
    • LENGTH(문자열)
      • 문자열의 길이를 반환해주는 함수이다.
      •  Ex. LENGTH('교촌치킨허니콤보') → 8
    • REPLACE(문자열, 변경 전 문자열 [변경 후 문자열]) *[]는 옵션
      • 문자열에서 변경 전 문자열을 찾아 변경 후 문자열로 바꿔주는 함수이다. 변경 후 문자열을 명시해 주지 않으면 문자열에서 변경 전 문자열을 제거한다.
      • Ex. REPLACE('교촌치킨허니콤보', '허니', '꿀') → 교촌치킨꿀콤보
      • Ex. SELECT REPLACE('교촌치킨허니콤보', '허니') → 교촌치킨콤보
  • 숫자 함수
    • ABS(수)
      • 수의 절대값을 반환해주는 함수이다.
        • ABS(-10) → 10 
      • SIGN(수)
        • 수의 부호를 반환해주는 함수이다. 양수이면 1, 음수이면 -1, 0이면 0을 반환한다
        • Ex. SIGN(-7) → 1
      • ROUND(수, [,자릿수]) *[]는 옵션
        • 수를 지정된 소수점 자릿수까지 반올림하여 반환해주는 함수이다.
        • 자릿수를 명시하지 않으면 기본값은 0이며 반올림된 정수로 반환한다.
        • 자릿수가 음수인 경우 지정된 정수브를 반올림하여 반환한다.
        • Ex. ROUND(178.356, 1) → 178.4
        • Ex. ROUND(178.356, -2) → 200
      • TRUNC(수 [,자릿수])
        • 수를 지정된 소수점 자릿수까지 버림하여 반환해주는 함수이다.
        • 자릿수를 명시하지 않았을 경우 기본 값을 0이며 버림된 정수를 반환한다.
        • 자릿수가 음수인 경우 지정된 정수부에서 버림하여 반환한다.
        • Ex. TRUNC(55.62, 1) → 55.6
        • Ex. TRUNC(55.62, -1) → 50
      • CELL(수)
        • 소수점 이하의 수를 올림한 정수를 반환해주는 함수이다.
        • SQL Server(MSSQL)의 경우 CELING(문자열)
        • Ex. CELL(72.86) → 73
        • Ex. CELL(-33.4) → 33
      • FLOOR(수)
        • 소수점 이하의 수를 버림한 정수를 반환해주는 함수이다.
        • 음수에서는 '버림'이 아닌 '내림'임에 주의하자
        • Ex. FLOOR(22.3) → 22
        • Ex. FLOOR(-22.3) → -23
      • MOD(수1, 수2)
        • 수1을 수2로 나눈 나머지를 반환해주는 함수이다.
        • MOD 함수의 두 번째 인자값이 0이면 첫 번째 인자 값이 결과로 도출된다.
        • MOD 함수의 두 인자값이 모두 음수이면 나머지도 그대로 음수값으로 도출된다.
        • Ex. MOD(15, 7) → 1
        • Ex. MOD(15, -4) → 3
    • 날짜 함수
      • SYSDATE
        • 현재의 연, 월, 일, 시, 분, 초를 반환해주는 함수이다.
        • nls_data_format에 따라서 sysdate의 출력 양식은 달라질 수 있다.
        • SQL Server(MSSQL)의 경우 GETDATE()
        • Ex. SYSDATE → 2022-08-31 20:12:56
      • EXTRACT(특정 단위 FROM 날짜 데이터)
        • 날짜 데이터에서 특정 단위(YEAR, MONTH, DAY HOUR, MINUTE, SECOND)만을 출력해서 반환해주는 함수이다,
        • Ex. EXTRACT(YEAR FROM SYSDATE) → 2022
        • Ex. EXTRACT(MONTH FROM SYSDATE) → 8
        • Ex. EXTRACT(DAY FROM SYSDATE) → 31
      • ADD_MONTH(날짜 데이터, 특정 개월 수)
        • 날짜 데이터에서 특정 개월 수를 더한 날짜를 반환해주는 함수이다.
        • 날짜의 이전 달이나 다음 달에 기준 날짜의 일자가 존재하지 않으면 해당 월의 마지막 일자가 반환된다.
        • SQL Server(MSSQL)의 경우 DATEADD(MONTH, 특정 개월 수, 날짜 데이터)
        • Ex. ADD_MONTH(TO_DATE('2022-08-31', 'YYYY-MM-DD'), -1) → 2022-09-30
    • 반환 함수
      • 명시적 형변환과 함시적 형변환
      • 데이터베이스에서 데이터 유형에 대한 형변환을 할 수 있는 방법은 두 가지가 있다.
        • 명시적 형변환: 변환 함수를 사용하여 데이터 유형 변환을 명시적으로 나타냄
        • 암시적 형변환: 데이터베이스가 내부적으로 알아서 데이터 유형을 변환함
      • Ex. VARCHAR 유형의 BIRTHDAY 컬럼을 숫자와 비교할 경우, 데이터 베이스는 오류를 뱉지 않고 내부적으로 BIRTHDAY 컬럼을 NUMBER형으로 변환하게 되는데 이럴 때 쓰이는 것이 암시적 형변환이다.
      • 암시적 형변환이 가능하다고해서 데이터 유형을 고려하기 않고 SQL 작성을 하는 것은 성능 저하를 유발한다. 
      • 따라서 되도록 명시적 형변환을 사용하는 것이 좋다.
      • 명시적 형변환에 쓰이는 함수
        • SQL Server(MSSQL)의 경우 CONVERT나 CAST 함수를 사용할 수 있다.
        • TO_NUMBER(문자열)
          •  문자열을 숫자형으로 변환해주는 함수이다.
          • Ex. TO_NUMBER('1234') → 1234
          • Ex. TO_NUMBER('abc') → Error 발생!
        • TO_CHAR(수 or 날짜 [, 포맷]) * []는 옵션
          • 수나 날짜형의 데이터를 포맷 형식의 문자형으로 변환해주는 함수이다.
          • Ex. TO_CHAR(1234) → '1234'
          • Ex. TO_CHAR(SYSDATE, 'YYYYMMDD HH24MISS') → 20220831 203309
        • TO_DATE(문자열, 포맷)
          • 포맷 형식의 문자형의 데이터를 날짜형으로 변환해주는 함수이다.
          • Ex. TO_DATE('20220831', 'YYYYMMDD') → '2022-08-31'
포맷 표현 의미 포맷표현 의미
YYYY HH 시(12)
MM HH24 시(24)
DD MI
    SS
  • NULL 관련 함수
    • NVL(인수1, 인수2)
      • 인수 1의 값이 NULL일 경우 인수2를 반환하고 NULL이 아닐 경우 인수1을 반환해주는 함수이다.
      • SQL Server(MMSQL)의 경우 ISNULL(인수1, 인수2)
      • Ex. NVL(REVIEW_SCORE, 0)
        • REVIEW_SCORE가 NULL인 경우 0를 반환
        • NULL이 아닌 경우 REVIEW_SCORE를 반환
    • NULLIF(인수1, 인수2)
      • 인수1과 인수2가 같으면 NULL을 반환한다.
      • 인수1과 인수2가 같지 않으면 인수1을 반환한다.
      • Ex. NULLIF(5, 5) → NULL
      • Ex. NULLIF(5, 3) → 5
    • COALESCE(인수1, 인수2, 인수3...)
      • NULL이 아닌 최초의 인수를 반환해주는 함수이다.
      • Ex. COALESCE(NULL, NULL, '000-000-000', '000@SQLD.COM', 5, NULL) → '000-000-000'
  • CASE
    • CASE는 함수와 성격이 같기는 하지만 표현방식이 함수라기보다는 구문에 가깝다고 할 수 있다.
    • 문장으로는 '~이면 ~이고', '~이면 ~이다' 식으로 표현되는 구문이다.
    • 필요에 따라 각 CASE를 여러 개로 늘릴 수도 있다.
    • 같은 기능을 하는 함수로는 Oracle의 DECODE 함수가 있다.
    • *[]는 옵션
    • 다음 구문은 같은 결과를 반환한다.
CASE WHEN SUBWAY_LINE='1' THEN 'BLUE'
	WHEN SUBWAY_LINE='2' THEN 'GREEN'
	WHEN SUBWAY_LINE='3' THEN 'ORANGE'
	[ELSE 'GRAY']
END

CASE SUBWAY_LINE
	WHEN '1' THEN 'BLUE'
    WHEN '2' THEN 'GREEN'
    WHEN '3' THEN 'ORANGE'
    [ELSE 'GRAY']
END

DECODE (SUBWAY_LINE,'1','BLUE','2','GREEN','3','ORANGE'[,GRAY])

 

WHERE 절

  • INSERT를 제외한 DML문을 수행할 때 원하는 데이터만 골라 수행할 수 있도록 해주는 구문이다.
  • 예를들면 NAME 컬럼이 '이지은'인 컬럼만 SELECT 할 수도 있고 '이지은'이 아닌 컬럼만 SELECT 할 수도 있다.
  • UPDATE나 DELETE도 마찬가지이다.
  • WHERE 절의 위치는 다음과 같다.
  • Ex. SELECT 컬럼1, 컬럼2 ... FROM 테이블 WHERE 조건절;
  • Ex. UPDATE 테이블명 SET 컬럼명 = 새로운 데이터 WHERE 조건절;
  • Ex. DELETE FROM 테이블 WHERE 조건절;
  • 다양한 WHERE 절에 대하여 알아보자.

 

비교 연산자

비교 연산자 의미 예시
= 같음 where col = 10
작음 where col < 10
<= 작거나 같음 where col <= 10
> where col > 10
>= 크거나 같음 where col >= 10
# 다음 쿼리는 CITY가 Paris인 행을 조회한다.
SELECT FIRST_NAME, LAST_NAME, CITY
	FROM MEMBER
    WHERE CITY = 'Paris';
    
# 다음 쿼리는 MEMBER_NO가 10보다 작은 행을 조회한다.
SELECT MEMBER_NO, FIRST_NAEM, LAST_NAME
	FROM MEMBER
    WHERE MEMBER_NO < 10;
    
# 다음 쿼리는 FIRST_NAME과 Mark의 데이터 타입이 맞지 않아 에러가 발생한다.
SELECT FIRST_NAME, LAST_NAME, EMAIL
	FROM MEMBER
    WHER FIRST_NAME = Mark;
    
# FIRST_NAME과 같은 문자형 컬럼을 비교 조건으로 사용하려면 우측 상수값을 반드시 인용부호로 감싸야한다.

 

부정 비교 연산자

부정 비교 연산자 의미 예시
!= 같지 않음 where col1 != 10
^= 같지 않음 where col1 ^= 10
<> 같지 않음 where col1 <> 10
not 컬럼명 = 같지 않음 where not col1 = 10
not 컬럼명 > 크지 않음 where not col1 > 10
# 다음 쿼리는 FAVORITES이 Y가 아닌 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
    WHERE FAVORITES <> 'Y';

 

SQL 연산자

SQL 연산자  의미 예시
BETWEEN A AND B A와 B 사이(A, B 포함) where col between 1 and 10
LIKE '비교 문자열' 비교 문자열을 포함 where col like '방탄%'
where col like '%소년단'
where col like '%탄소년%'
where col like '방_소%'
IN (LIST) LIST 중 하나와 일치 where col in (1, 3, 5)
IS NULL NULL 값 where col is null
# 다음 쿼리는 PLAY_ID가 1 이상, 5이하인 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE PLAY_ID BETWEEN 1 AND 5;

# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE PLAY_ID >= 1 AND PLAY_ID <=5;

# 다음 쿼리는 NAME이 Classical로 시작되는 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE NAME LIKE 'Classical%';

# 다음 쿼리는 NAME이 Music으로 끝나는 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE NAME LIKE '%Music';

# 다음 쿼리는 NAME이 M으로 시작하고 S로 끝나는 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE NAME LIKE 'M&S';

# 다음 쿼리는 NAMEDP 101이 포함된 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE NAME LIKE '&101%';

# 다음 쿼리는 TITLE이 IT Staff이거나 IT Manager인 행을 조회한다.
SELECT LAST_NAME, FIRST_NAEM, TITLE
	FROM EMPLOYEE
WHERE TITLE IN ('IT Staff', 'IT Manager');

# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT LAST_NAME, FIRST_NAME, TITLE
	FROM EMPLOYEE
WHERE (TITLE = 'IT Staff' OR TITLE = 'IT Manager');

# 다음 쿼리는 COMPANY가 NULL인 행을 조회한다.
SELECT FIRST_NAME, LAST_NAME, COMPANY
	FROM MEMBER
WHERE COMPANY IS NULL;

 

부정 SQL 연산자

부정 SQL 연산자 의미 예시
NOT BETWEEN A AND B A와 B의 사이가 아님(A, B 미포함) where col not between 1 and 10
NOT IN (LIST) LIST 중 일치하는 것이 없음 where col not in (1, 3, 5)
IS NOT NULL NULL 값이 아님 where col is not null
# 다음 쿼리는 PLAY_ID가 1이상, 5이하가 아닌 행을 조회한다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE PLAY_ID NOT BETWEEN 1 AND 5;

# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE NOT (PLAY_ID BTWEEN 1 AND 5);

SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE NOT (PLAY_ID >= 1 AND PLAY_ID <= 5);

SELECT PLAY_ID, NAME, FAVORITES
	FROM PLAY_LIST
WHERE PLAY_ID < 1 OR PLAY_ID > 5;

# 다음 쿼리는 TITLE이 IT Staff와 IT Manager가 아닌 행을 조회한다.
SELECT LAST_NAME, FIRST_NAME, TITLE
	FROM EMPLOYEE
WHERE TITLE NOT IN ('IT Staff', 'IT Manager');

# 위의 쿼리는 다음과 같이 표현할 수도 있다.
SELECT LAST_NAME, FIRST_NAME, TITLE
	FROM EMPLOYEE
WHERE NOT (TITLE IN ('IT Staff', 'IT Manager'));

SELECT LAST_NAME, FIRST_NAME, TITLE
	FROM EMPLOYEE
WHERE NOT (TITLE = 'IT Staff' OR TITLE = 'IT Manager');

SELECT LAST_NAME, FIRST_NAME, TITLE
	FROM EMPLOYEE
WHERE TITLE <> 'IT Staff' AND TITLE <> 'IT Manager';

# 다음 쿼리는 COMPANY가 NULL이 아닌 행을 조회한다.
SELECT FIRST_NAME, LAST_NAME, COMPANY
	FROM MEMBER
WHERE COMPANY IS NOT NULL;

 

논리 연산자

  • 논리 연산자에는 처리 순서가 존재하는데 SQL에 명시된 순서와는 관계없다.
  • () → NOT → AND → OR 순으로 처리된다.
논리 연산자 의미 예시
NOT TRUE이면 FALSE이고 FALSE이면 TRUE where not col > 10
AND 모든 조건이 TRUE여야 함 where col>1 and col<10
OR 하나 이상의 조건이 TRUE여야 함 where col=1 or col=10

 

GROUP BY, HAVING 절

  • GROUP BY
    • GROUP BY는 말 그대로 데이터를 그룹별로 묶을 수 있도록 해주는 절이다.
    • GROUP 뒤에 수단의 전치사인 BY가 붙었기 때문에 GROUP BY 뒤에는 그룹핑의 기준이 되는 컬럼이 온다.
    • 컬럼은 하나또는 그 이상이 될 수 있다.
  • 집계 함수
    • 데이터를 그룹별로 나누면 그룹별로 집계 데이터를 도출하는 것이 가능해진다.
COUNT(*) 전체 Row를 Count하여 반환
COUNT(컬럼) 컬럼값이 Null인 Row를 제외하고 Count하여 반환
COUNT(DISTINCT 컬럼) 컬럼값이 Null이 아닌 Row에서 중복을 제거한 Count를 반환
SUM(컬럼) 컬럼값들의 합계 반환
AVG(컬럼) 컬럼값들의 평균 반환
MIN(컬럼) 컬럼값들의 최솟값 반환
MAX(컬럼) 컬럼값들의 최댓값 반환
  • HAVING
    • HAVING 절은 GROUP BY 절을 사용할 때 WHERE 절처럼 사용하는 조건절이라고 생각하면된다.
    • 주로 데이터를 그룹핑한 후 특정 그룹을 골라낼 때 사용한다.
    • HAVING 절은 논리적으로 GROUP BY 절 이후에 수행되기에 그룹핑 후에 가능한 집계 함수로 조건을 부여할 수 있다.
    • HAVING 절은 논리적으로 SELECT 절 전에 수행되기에 SELECT 절에 명시되지 않은 집계 함수로도 조건을 부여하는 것이 가능하다.
    • 주의할 점은 WHERE 절을 사용해도 되는 조건까지 HAVING 절로 써버리면 성능상 불리할 수 있다는 점이다.
    • WHERE 절에서 필터링을 선행해야 GROUP BY 할 데이터량이 줄어들어 성능에 유리하다.
SELECT 문의 논리적 수행 순서

SELECT        → 5
FROM           → 1 
WHERE        → 2
GROUP BY   → 3
HAVING        → 4
ORDER BY   → 6

 

ORDER BY 절

  • ORDER BY
    • ORDER BY 절은 SELECT 문에서 논리적으로 맨 마지막에 수행된다.
    • ORDER BY 절을 사용하여 SELECT한 데이터를 정렬할 수 있다.
    • ORDER BY 절을 따로 명시하지 않으면 데이터는 임의의 순서대로 출력된다.
    • ORDER BY 절 뒤에는 정렬의 기준이 되는 컬럼이 오게된다.
    • 기준이 되는 컬럼은 하나 또는 그 이상이 될 수도 있다.
    • ORDER BY 절 뒤에 오는 컬럼에는 옵션이 붙을 수 있으며 종류는 다음과 같다.
      • ASC(Ascending) : 오름차순
      • DESC(Descending) : 내림차순
      • 옵션 생략 시 ASC가 기본값이 된다.
    • 정렬의 기준이 되는 컬럼에 NULL 데이터가 포함되어 있는 경우 데이터베이스 종류에 따라 정렬의 위치가 달라진다.
    • Oracle의 경우에는 NULL을 최댓값으로 취급하기 때문에 오름차순을 했을 경우 맨 마지막에 위치한다.(SQL Server는 반대)
    • 만약 순서를 변경하고 싶다면 ORDER BY 절에 NULLS FIRST, NULLS LAST 옵션을 써서 NULL의 정렬상 순서를 변경할 수 있다.

 

JOIN

  • JOIN이란?
    • 테이터베이스에서 조인이란 각기 다른 테이블을 한 번에 보여줄 때 쓰는 쿼리이다.
    • 실무에서 SQL을 작성할 때 8할이 JOIN 쿼리라고 얘기해도 무방하다.
    • JOIN되는 두 테이블에 모두 존재하는 컬럼의 경우 컬럼명 앞에 반드시 테이블명이나 ALIAS를 명시해주어야 함
  • EQUI JOIN
    • EQUI JOIN은 Equal(=) 조건으로 JOIN하는 것으로 가장 흔히 볼 수 있는 JOIN의 방식이라고 할 수 있다
SELECT A.PRODUCT_CODE,
	A.PRODUCT_NAME,
    B.MEMBER_ID,
    B.CONTENT,
    B.REG_DATE
FROM PRODUCT A,
	PRODUCT_REVIEW B
WHERE A.PRODUCT_CODE = B.PRODUCT_CODE
	AND A.PRODUCT_CODE = '100001';
  • Non EQUI JOIN
    • Non EQUI JOIN은 Equal(=) 조건이 아닌 다른 조건(BETWEEN, >, >=, <, <=)으로 JOIN 하는 방식이다.
    • 예를 들어 이벤트 기간 동안 리뷰를 작성한 고객에게 사은품을 주는 행사를 하고 있다고 가정해보자.
    • 이 경우 리뷰 테이블과 이벤트 테이블이 JOIN되어야 할 것이다.
SELECT A.EVENT_NAME,
	B.MEMBER_NAME,
    B.CONTENT,
    B.REG_DATE
FROM EVENT A,
	PRODUCT_REVIEW B
WHERE B.REG_DATE BETWEEN A.START_DATE AND A.END_DATE;
  • OUTER JOIN
    • OUTER JOIN은 앞서 본 JOIN과는 다르게 JOIN 조건에 만족하지 않는 행들도 출력되는 형태이다.
    • LEFT OUTER JOIN의 경우 LEFT TABLE과 RIGHR TABLE의 데이터 중 JOIN에 성곤한 데이터와 그렇지 못한 나머지 LEFT TABLE의 데이터가 함께 출력된다.
    • Oracle에서는 모든 행이 출력되는 테이블의 반대편 테이블의 옆에(+) 기로를 붙여 작성해주면 된다.
# LEFT OUTER JOIN이다.
SELECT A.PRODUCT_CODE,
	A.PRODUCT_NAME,
    B.MEMBER_ID,
    B.CONTENT,
    B.REG_DATE
FROM PRODUCT A,
	PRODUCT_REVIEW B
WHERE A.PRODUCT_CODE = B.PRODUCT_CODE(+);

 

STANDARD JOIN

  • DBMS가 여러개가 존재하는데 호환성 이슈가 발생하여 하나의 표준을 정한것이다.
  • ANSI SQL, 표준 조인이라는 말을 많이 사용한다.
  • INNER JOIN
    • JOIN 조건에 충족하는 데이터만 출력되는 방식이다.
    • 앞서 본 SQL과의 차이점은 JOIN 조건을 ON 절을 사용하여 작성해야 한다는 점이다.
SELECT A.PRODUCT_CODE,
	A.PRODUCT_NAME,
    B.MEMBER_ID,
    B.CONTENT,
    B.REG_DATE
FROM PRODUCT A INNER JOIN PRODUCT REVIEW B
	ON A.PRODUCT_CODE = B.PRODUCT_CODE;
  • OUTER JOIN
    • JOIN 조건에 충족하는 데이터가 아니어도 출력될 수 있는 방식이다.
    • LEFT OUTER JOIN
      • SQL에서  왼쪽에 표기된 테이블의 데이터는 무조건 출력되는 JOIN이다.
      • 오른쪽 테이블에 JOIN되는 데이터가 없는 ROW들은 오른쪽 테이블 컬럼의 값이 NULL로 출력된다.
    • RIGHT OUTER JOIN
      • SQL에서 오른쪽에 표기된테이블의 데이터는 무조건 출력되는 방식이다.
      • 왼족 테이블에 JOIN되는 데이터가 없는 ROW들은 왼쪽 테이블 컬럼의 값이 NULL로 출력된다.
    • FULL OUTER JOIN
      • 왼쪽, 오룬쪽 테이블의 데이터가 모두 출력되는 방식이다.
      • LEFT OUTER JOIN과 RIGHT OUTER JOIN의 합집합이라고 이해하면 쉽다.(단 중복값은 제거)
  • NATURAL JOIN
    • A 테이블과 B 테이블에서 같은 이름을 가진 컬럼들이 모두 동일한 데이터를 가지고 있을 경우 JOIN이 되는 방식이다.
    • SQL Server(MSSQL)에서는 지원하지 않는다.
    • Oracle의 경우 USING 조건절을 사용하여 같은 이름을 가진 컬럼중 원하는 컬럼만 JOIN에 사용할 수도 있다.
    • 단, SELECT 절에서 USING 절로 정의된 컬럼 앞에는 별도의 ALIAS나 테이블명을 붙이지 않아야 한다.
  • CROSS JOIN
    • 예선 수학 시간에 경우의 수에 대해 배운 적이 있을 것이다.
    • 비슷한 맥락으로 CROSS JOIN은 A 테이블과 B 테이블 사이에 JOIN 조건이 없는 경우, 조합할 수 있는 모든 경우를 출력하는 방식이다.
    • 다른 말로 Cartesian Product라고 표현하기도 한다.

문제 풀이중 팁

  • NULL과의 연산 결과는 False이므로 조건값이 늘 거짓이 되어 아무 데이터도 출력되지 않는다. 
  • CASE 문에서 ELSE 뒤의 값이 DEFAULT 값이 되고 별도의 ELSE가 없을 경우 NULL 값이 DEFAULT 값이 된다.
  • 나누기 연산을 할때 0으로 나누려하면 에러가 발생한다.
  • NATURAL JOIN은 공통 컬럼 앞에 OWNER 명을 붙이면 에러가 발생한다.
  • ALIAS를 별도로 지정해주지 않으면 컬럼명이 대문자로 출력된다.
  • ORDER BY 절에는 컬럼명을 명시해줄 수도 있고 SELECT 절에 기술된 컬럼의 순서를 숫자로 명시해줄 수도 있다.
  • AVG, MAX 함수는 각각 NULL 값을 제외하고 계산된다.
  • HAVING 절은 주로 GROUP BY 절 뒤에 오면서 집계 데이터에 대한 조건을 부여하지만 테이블 전체가 한 개의 그룹이 되는 경우 HAVING만 단독으로 사용할 수 있다.

+ Recent posts