반응형
서브쿼리(Subquery)
- SQL문 내부에 함수가 들어갈 수 있는 위치에 또 다른 독립적인 SQL문을 넣는 것
- 서브쿼리를 품고 있는 쿼리를 메인쿼리(Main Query)라고 부름
- 메인쿼리의 칼럼을 사용할 수 있으며(메인쿼리에서는 서브쿼리의 칼럼 사용 불가), ORDER BY절은 사용할 수 없음
- 단일행 비교연산자를 사용할 경우 결과는 1건 이하, 2건 이상의 결과를 반환할때는 다중행 비교연산자를 사용
- 메인쿼리 칼럼 사용 여부에 따라 연관 서브쿼리, 비연관 서브쿼리로 구분
- 함수가 들어가는 위치에 따라 스칼라 서브쿼리, 인라인 뷰, 중첩 서브쿼리로 구분
스칼라 서브쿼리
- SELECT문의 칼럼이 입력되는 위치(SELECT, ORDER BY 등)에 들어가는 서브쿼리
- 칼럼이 입력되는 위치에 삽입되므로 스칼라 서브쿼리의 결과는 하나의 칼럼만을 가져야 함
인라인 뷰
- FROM절의 테이블이 입력되는 위치에 들어가는 서브쿼리
- 쿼리 실행 시 동적으로 생성되는 테이블
- 복잡한 쿼리를 단계적으로 작성할 수 있고 전체가 아닌 테이블의 일부분만 불러와 비교 횟수를 줄일 수 있음
- SELECT절이 중첩되어 쿼리가 복잡해지지만 별명(Alias) 사용해 가독성을 높일 수 있음
중첩 서브쿼리
- WHERE절과 HAVING절에 쿼리가 중첩되어 들어가는 서브쿼리
- 메인쿼리에서 참조하고 있는 테이블의 칼럼을 서브쿼리 내에서 다시 사용 가능
- 스칼라 서브쿼리나 인라인 뷰와 달리 반환하는 값의 형태가 하나가 아닌 다양한 값 반환 가능
- 단일행(Single Row): 1건 이하의 데이터를 반환, 단일행 비교연산자(=, >, < 등)의 연산 대상으로 사용
- 다중행(Multi Row): 2건 이상의 데이터를 반환, 다중행 비교연산자(IN, ALL, EXIST 등)의 연산 대상으로 사용
- 다중칼럼(Multi Column): 여러 칼럼의 값을 반환(벡터), 여러 칼럼을 가진 테이블 형태
뷰(View)
- 참조 시 동적으로 메모리 생성되는 임시 또는 가상 테이블
- CREATE VIEW로 시작되는 DDL 코드로 생성 가능
- 복잡하고 긴 SELECT문을 만들어두고 사용할 수 있어 쿼리를 간결하고 단순하게 작성할 수 있지만 삽입, 수정, 삭제에 대한 제한이 있고 인덱스를 가질 수 없는 단점 존재
집합연산자
- 두 테이블에 대한 집합 연산(합집합, 교집합 등)을 수행하는 연산자
- JOIN과 달리 특정한 기준키 없이 두 테이블의 레코드들에 대하여 연산을 수행하므로 두 테이블의 스키마가 동일해야 함
- 스키마 구성은 동일하나 칼럼의 이름은 다를 수 있는데, 반환되는 칼럼의 이름은 첫 번째 테이블을 따름
UNION ALL / UNION
- 두 테이블에 포함된 모든 레코드들을 모두 포함하는 합집합 연산을 수행
- 두 테이블에 모두에 포함된 공통의 레코드(합집합)는 중복 레코드라도 함
- 중복 레코드들을 중복된 개수만큼 그대로 포함시키는 것은 UNION ALL, 하나만 포함시키는 것은 UNION(한쪽 테이블 내에서의 중복까지 제거)
INTERSECT
- 두 테이블에 공통적으로 포함된 레코드만을 포함하는 교집합 연산을 수행
MINUS / EXCEPT
- 왼쪽 테이블에서 두 테이블에 공통적으로 포함된 레코드들을 제외시킨 결과를 반환하는 차집합 연산을 수행




그룹함수
- GROUP BY절에 따른 결과에 대해서 그룹 별로 연산을 수행하는 함수
ROLLUP
- GROUP BY절에 들어가는 칼럼을 대상으로 하위 그룸핑을 수행하는 함수
- 마지막 행(Row)에 전체를 하나로 묶은 그룹을 추가
SELECT
brand AS '브랜드',
SUM(sales_count) AS '판매수'
FROM car
GROUP BY ROLLUP(brand);
=> 브랜드 | 판매수
KG 모빌리티 | 290
기아 | 642
제네시스 | 725
현대 | 728
NULL | 2385
SELECT
brand AS '브랜드',
name AS '자동차명',
SUM(sales_count) AS '판매수'
FROM car
GROUP BY ROLLUP(brand, name);
=> 브랜드 | 자동차명 | 판매수
KG 모빌리티 | 렉스턴 스포츠 칸 | 140
KG 모빌리티 | 코란도 투리스모 | 150
KG 모빌리티 | NULL | 290
기아 | EV9 | 153
기아 | K9 | 259
기아 | 카니발 | 230
기아 | NULL | 642
제네시스 | G90 | 395
제네시스 | GV80 | 330
제네시스 | NULL | 725
현대 | 싼타페 | 296
현대 | 아이오닉N | 122
현대 | 팰리세이드 | 310
현대 | NULL | 728
NULL | NULL | 2385
CUBE
- ROLLUP과 비슷하지만 1차적인 하위 그룹핑만 수행하는데 반하여 조합 가능한 모든 경우로 그룹핑을 수행
- 인자가 1개인 경우 ROLLUP과 동일, 두 개 이상인 경우 결과는 다름
SELECT
brand AS '브랜드',
name AS '자동차명',
SUM(sales_count) AS '판매수'
FROM car
GROUP BY CUBE(brand, name);
=> 브랜드 | 자동차명 | 판매수
KG 모빌리티 | 렉스턴 스포츠 칸 | 140
KG 모빌리티 | 코란도 투리스모 | 150
KG 모빌리티 | NULL | 290
기아 | EV9 | 153
기아 | K9 | 259
기아 | 카니발 | 230
기아 | NULL | 642
제네시스 | G90 | 395
제네시스 | GV80 | 330
제네시스 | NULL | 725
현대 | 싼타페 | 296
현대 | 아이오닉N | 122
현대 | 팰리세이드 | 310
현대 | NULL | 728
NULL | 렉스턴 스포츠 칸 | 140
NULL | 코란도 투리스모 | 150
NULL | EV9 | 153
NULL | K9 | 259
NULL | 카니발 | 230
NULL | G90 | 395
NULL | GV80 | 330
NULL | 싼타페 | 296
NULL | 아이오닉N | 122
NULL | 팰리세이드 | 310
NULL | NULL | 2385
GROUPING SETS
- 그룹핑할 대상을 지정하는 함수
- ROLLUP, CUBE의 경우 소계, 총계 형태로 자동으로 그룹핑되지만 GROUPING SETS는 입력된 인자에 대해서만 소계를 구할 때 사용
- 인자에 ROLLUP이나 CUBE 함수를 넣을 수 있음
SELECT
brand AS '브랜드',
name AS '자동차명',
SUM(sales_count) AS '판매수'
FROM car
GROUP BY GROUPING SETS(brand, name);
=> 브랜드 | 자동차명 | 판매수
KG 모빌리티 | NULL | 290
기아 | NULL | 642
제네시스 | NULL | 725
현대 | NULL | 728
NULL | 렉스턴 스포츠 칸 | 140
NULL | 코란도 투리스모 | 150
NULL | EV9 | 153
NULL | K9 | 259
NULL | 카니발 | 230
NULL | G90 | 395
NULL | GV80 | 330
NULL | 싼타페 | 296
NULL | 아이오닉N | 122
NULL | 팰리세이드 | 310
GROUPING
- ROLLUP, CUBE, GROUPING SETS과 함께 사용하여 소계에 해당하는 결과 행과 그렇지 않은 행을 구분
- 소계에 해당하는 결과 행에 경우 1, 그렇지 않은 경우 0을 반환, CASE문과 함께 사용하여 소계나 총계 표시
SELECT
CASE GROUPING(brand) WHEN 1 THEN '총계' ELSE brand END AS '브랜드',
SUM(sales_count) AS '판매수'
FROM car
GROUP BY ROLLUP(brand);
=> 브랜드 | 판매수
KG 모빌리티 | 290
기아 | 642
제네시스 | 725
현대 | 728
총계 | 2385
윈도우함수
- 행과 행 간의 관계를 나타내는 연산을 쉽게 하기 위한 함수
- GROUP BY 연산과 비슷하지만 각 행을 대상으로 연산 수행 후 새로운 구성을 만드는 GROUP BY 연산과는 달리 새로운 행을 추가하거나 기존의 값을 변경
- 모든 윈도우함수는 OVER 키워드와 함께 사용
순위함수
- 순위를 구할 때 사용하는 함수
- RANK: 동일 순위는 같은 순위값, 순위값은 앞 순위까지의 누적 개수 +1
- DENSE_RANK: 동일 순위는 같은 순위값, 순위값은 앞 순위의 +1
- ROW_NUMBER: 동일 순위라도 각각의 행이 고유 순위값을 가짐
SELECT
student_name AS '학생명',
test_score AS '시험점수',
RANK() OVER(ORDER BY test_score DESC) AS 'RANK',
DENSE_RANK() OVER(ORDER BY test_score DESC) AS 'DENSE_RANK',
ROW_NUMBER() OVER(ORDER BY test_score DESC) AS 'ROW_NUMBER'
FROM test_result;
=> 학생명 | 시험점수 | RANK | DENSE_RANK | ROW_NUMBER
박철수 | 94 | 1 | 1 | 1
김수현 | 91 | 2 | 2 | 2
박지훈 | 91 | 2 | 2 | 3
이상진 | 84 | 4 | 3 | 4
박정민 | 84 | 4 | 3 | 5
오진아 | 70 | 6 | 4 | 6
집계함수
- OVER절을 사용하여 파티션 별로 집계하거나 누적 집계를 계산
- COUNT: 값이 NULL인 행을 제외한 행의 개수를 파티션 별로 집계하거나 누적 집계를 계산하여 반환
- SUM: 입력된 칼럼에 대해 파티션 별 합계를 구하거나 누적 합계를 계산하여 반환
- AVG: 입력된 칼럼에 대해 파티션 별 평균을 구하거나 누적 평균을 계산하여 반환
- MIN: 입력된 칼럼에 대해 파티션 별 최솟값을 반환
- MAX: 입력된 칼럼에 대해 파티션 별 최댓값을 반환
SELECT
DISTINCT brand AS '브랜드',
COUNT(*) OVER(PARTITION BY brand) AS '차량수',
SUM(price) OVER(PARTITION BY brand) AS '총 가격',
AVG(price) OVER(PARTITION BY brand) AS '평균 가격',
MIN(price) OVER(PARTITION BY brand) AS '최소 가격',
MAX(price) OVER(PARTITION BY brand) AS '최대 가격'
FROM car;
=> 브랜드 | 차량수 | 총 가격 | 평균 가격 | 최소 가격 | 최대 가격
KG 모빌리티 | 2 | 79690000 | 39845000.0000 | 35000000 | 44690000
기아 | 3 | 253410000 | 84470000.0000 | 77440000 | 92000000
제네시스 | 2 | 182140000 | 91070000.0000 | 78300000 | 103840000
현대 | 3 | 171000000 | 57000000.0000 | 45000000 | 76000000
행 순서함수
- FIRST_VALUE: 파티션 별로 그룹핑하여 가장 처음 값 반환
- LAST_VALUE: 파티션 별로 그룹핑하여 가장 마지막 값 반환
- LAG: 입력된 인자의 값만큼 이전 행의 값을 반환
- LEAD: 입력된 인자의 값만큼 이후 행의 값을 반환
SELECT
DISTINCT brand AS '브랜드',
FIRST_VALUE(price) OVER(PARTITION BY brand ORDER BY price DESC) AS 'FIRST_VALUE'
FROM car;
=> 브랜드 | FIRST_VALUE
KG 모빌리티 | 44690000
기아 | 92000000
제네시스 | 103840000
현대 | 76000000
SELECT
brand AS '브랜드',
name AS '자동차명',
price AS '가격',
LAG(name, 2) OVER(ORDER BY price DESC) AS 'LAG',
LEAD (name, 2) OVER(ORDER BY price DESC) AS 'LEAD'
FROM car;
=> 브랜드 | 자동차명 | 가격 | LAG | LEAD
제네시스 | G90 | 103840000 | NULL | EV9
기아 | 카니발 | 92000000 | NULL | GV80
기아 | EV9 | 83970000 | G90 | K9
제네시스 | GV80 | 78300000 | 카니발 | 아이오닉N
기아 | K9 | 77440000 | EV9 | 팰리세이드
현대 | 아이오닉N | 76000000 | GV80 | 싼타페
현대 | 팰리세이드 | 50000000 | K9 | 렉스턴 스포츠 칸
현대 | 싼타페 | 45000000 | 아이오닉N | 코란도 투리스모
KG 모빌리티 | 렉스턴 스포츠 칸 | 44690000 | 팰리세이드 | NULL
KG 모빌리티 | 코란도 투리스모 | 35000000 | 싼타페 | NULL
비율함수
- 파티션 별로 전체 개수나 합계를 구한 후 그에 대한 비율을 구하는 함수
- CUME_DIST: 파티션 별로 전체 개수에 대한 누적 백분율을 소수점 단위로 계산하여 반환, 마지막 행이 1
- PERCENT_RANK: 파티션 별로 순서별 백분율을 반환, 가장 첫 행이 0, 마지막 행이 1
- NTILE: 파티션을 N등분하여 1부터 N까지의 등급 값을 반환
- RATIO_TO_REPORT: 파티션 별 합계에 대한 비율을 계산하여 반환
SELECT
brand AS '브랜드',
name AS '자동차명',
price AS '가격',
CUME_DIST() OVER(ORDER BY price) AS 'CUME_DIST',
PERCENT_RANK() OVER(ORDER BY price) AS 'PERCENT_RANK',
NTILE(5) OVER(ORDER BY price) AS 'NTILE',
RATIO_TO_REPORT(price) OVER(PARTITION BY brand) AS 'RATIO_TO_REPORT'
FROM car
ORDER BY price DESC;
=> 브랜드 | 자동차명 | 가격 | CUME_DIST | PERCENT_RANK | NTILE | RATIO_TO_REPORT
제네시스 | G90 | 103840000 | 1.0 | 1.0 | 5 | 0.151
기아 | 카니발 | 92000000 | 0.9 | 0.8888888888888888 | 5 | 0.134
기아 | EV9 | 83970000 | 0.8 | 0.7777777777777778 | 4 | 0.122
제네시스 | GV80 | 78300000 | 0.7 | 0.6666666666666666 | 4 | 0.114
기아 | K9 | 77440000 | 0.6 | 0.5555555555555556 | 3 | 0.113
현대 | 아이오닉N | 76000000 | 0.5 | 0.4444444444444444 | 3 | 0.111
현대 | 팰리세이드 | 50000000 | 0.4 | 0.3333333333333333 | 2 | 0.073
현대 | 싼타페 | 45000000 | 0.3 | 0.2222222222222222 | 2 | 0.066
KG 모빌리티 | 렉스턴 스포츠 칸 | 44690000 | 0.2 | 0.1111111111111111 | 1 | 0.065
KG 모빌리티 | 코란도 투리스모 | 35000000 | 0.1 | 0.0 | 1 | 0.051
Top N 쿼리
- 멜론 차트 100과 같이 상위 N 순위까지 추출하는 쿼리
ROWNUM 함수
- 현재 저장된 데이터를 그대로 두고 각 행에 순차적인 번호를 붙여주는 함수
- 테이블의 첫 행부터 차례로 순회하면서 값을 반환하기 때문에 중간을 건너뛰고 값을 가져올 수 없음
- WHERE 조건이 FALSE가 되면 순회를 멈추고 결과를 반환(<, <= 비교연산자만 WHERE 조건으로 사용)
- ORDER BY와 함께 사용할 경우 행에 번호가 매겨지고 나서 정렬되므로 출력되는 번호가 뒤죽박죽 될 수 있어 주의해야 함
SELECT
ROWNUM
student_name AS '학생명',
test_score AS '시험점수'
FROM test_result WHERE ROWNUM <= 5
=> ROWNUM | 학생명 | 시험점수
1 | 박철수 | 94
2 | 김수현 | 91
3 | 박지훈 | 91
4 | 이상진 | 84
5 | 박정민 | 84
SELECT
ROWNUM
student_name AS '학생명',
test_score AS '시험점수'
FROM test_result WHERE ROWNUM = 5
=> ROWNUM | 학생명 | 시험점수
# 대소비교가 아닌 등식비교를 할 경우
# ROWNUM이 1일 때 조건이 FALSE가 되어 더 이상 순회되지 않아 아무런 결과가 나오지 않음
윈도우함수의 순위함수
- RANK, DENSE_RANK, ROW_NUMBER 함수를 사용해서 Top N 쿼리 작성 가능
SELECT * FROM (
SELECT
student_name AS '학생명',
test_score AS '시험점수',
RANK() OVER(ORDER BY test_score DESC) AS 'RANK',
DENSE_RANK() OVER(ORDER BY test_score DESC) AS 'DENSE_RANK',
ROW_NUMBER() OVER(ORDER BY test_score DESC) AS 'ROW_NUMBER'
FROM test_result
) AS TR WHERE TR.ROW_NUMBER <= 5;
=> 학생명 | 시험점수 | RANK | DENSE_RANK | ROW_NUMBER
박철수 | 94 | 1 | 1 | 1
김수현 | 91 | 2 | 2 | 2
박지훈 | 91 | 2 | 2 | 3
이상진 | 84 | 4 | 3 | 4
박정민 | 84 | 4 | 3 | 5
계층형 질의와 셀프 조인
계층형 질의
- 계층형 데이터 모델을 다룰 때 상위(부모) 노드에서 하위(자식) 노드로 연쇄적으로 데이터에 접근해서 결과를 조회해야 할 경우 사용
- 계층 구조를 가지는 칼럼을 대상으로 데이터를 출력할 때 키워드를 제공
| 키워드 | 설명 |
| LEVEL | 레벨 또는 깊이(Depth)를 반환, 루트 노드가 1이고 레벨이 내려갈때마다 1씩 증가 |
| SYS_CONNECT_BY_PATH | 최상위 루트 노드로부터 현재 노드까지의 경로를 출력하는 함수 |
| START WITH | 경로의 시작이 되는 루트 노드의 조건 지정 |
| CONNECT BY | 부모 노드로부터 자식 노드로의 경결을 지정 |
| CONNECT_BY_ROOT | 루트 노드의 지정된 칼럼값 반환 |
| CONNECT_BY_ISLEAF | 가장 말단 노드이면 1, 그 외는 0 반환 |
| PRIOR | 바로 상위 부모 노드를 반환 |
| NOCYCLE | 사이클 발생 이후에 데이터를 전개하지 않음으로써 무한 루프 방지 |
| ORDER SIBLINGS BY | 같은 레벨의 형제 노드끼리 정렬 |
순방향 전개(프·자·부·순)
- CONNECT BY PRIOR 자식 = 부모
- 상위 노드로 부모를 지정하므로 부모 → 자식으로 이어지는 전개
역방향 전개(프·부·자·역)
- CONNECT BY PRIOR 부모 = 자식
- 상위 노드로 자식을 지정하므로 자식 → 부모로 이어지는 전개
SELECT * FROM (
SELECT
LEVEL AS 'LVL',
parent_category_id AS '부모 카테고리ID',
category_id AS '카테고리ID',
category_name AS '카테고리명'
FROM category
START WITH parent_category_id IS NULL
CONNECT BY PRIOR category_id = parent_category_id
) AS TR ORDER BY TR.LVL;
=> LVL | 부모 카테고리ID | 카테고리ID | 카테고리명
1 | NULL | 1 | 한식
1 | NULL | 2 | 중식
1 | NULL | 3 | 일식
1 | NULL | 4 | 분식
2 | 1 | 5 | 김치찌게
2 | 1 | 6 | 된장찌게
2 | 1 | 7 | 불고기
2 | 2 | 8 | 짜장면
2 | 2 | 9 | 짬뽕
2 | 2 | 10 | 탕수육
2 | 3 | 11 | 초밥
2 | 3 | 12 | 라멘
2 | 3 | 13 | 소바
2 | 4 | 14 | 떡볶이
2 | 4 | 15 | 김밥
2 | 4 | 16 | 라면
셀프 조인
- 같은 테이블에 대해서 조인을 수행
- 계층에 깊이가 깊어질수록 쿼리가 반복되고 길어짐 → 계층형 질의를 사용
SELECT
B.parent_category_id AS '부모 카테고리ID',
A.category_name AS '부모 카테고리명',
B.category_id AS '카테고리ID',
B.category_name AS '카테고리명'
FROM category A, category B
WHERE A.category_id = B.parent_category_id
=> 부모 카테고리ID | 부모 카테고리명 | 카테고리ID | 카테고리명
1 | 한식 | 5 | 김치찌게
1 | 한식 | 6 | 된장찌게
1 | 한식 | 7 | 불고기
2 | 중식 | 8 | 짜장면
2 | 중식 | 9 | 짬뽕
2 | 중식 | 10 | 탕수육
3 | 일식 | 11 | 초밥
3 | 일식 | 12 | 라멘
3 | 일식 | 13 | 소바
4 | 분식 | 14 | 떡볶이
4 | 분식 | 15 | 김밥
4 | 분식 | 16 | 라면
PIVOT절과 UNIPIVOT절
- 피벗(PIVOT)이란 테이블의 행(Row)과 열(Column)을 전환하여 테이블을 재구성하는 것
- 행과 열을 바꾸는 관점에 따라 피벗(PIVOT), 언피벗(UNIPIVOT)을 구분
- 함수가 아닌 FROM절 뒤에 기술하는 구문, SELECT절보다 먼저 수행
PIVOT절
- 행 → 열 전환
- 지정된 칼럼의 각 행 속성값들이 새로운 칼럼 헤더가 되고 이에 맞게 전체 속성값들을 재배치
SELECT * FROM FOOD;
=> FOOD_ID | NAME | CATEGORY
1 | 김치찌게 | 한식
2 | 된장찌게 | 한식
3 | 불고기 | 한식
4 | 초밥 | 일식
5 | 라멘 | 일식
6 | 짜장면 | 중식
7 | 탕수육 | 중식
8 | 양장피 | 중식
SELECT * FROM (
SELECT CATEGORY FROM FOOD
) PIVOT (
COUNT(*) FOR CATEGORY IN ('한식' AS 한식, '일식' AS 일식, '중식' AS 중식)
);
=> 한식 | 중식 | 일식
3 | 2 | 3
UNPIVOT절
- 열 → 행 전환
- 칼럼 헤더들이 한 칼럼의 각 행 속성값이 되고, 이에 맞게 전체 속성값들을 재배치
SELECT * FROM PRODUCT_SALES;
=> PRODUCT_NAME | Y2021_SALES_COUNT | Y2022_SALES_COUNT | Y2023_SALES_COUNT | Y2024_SALES_COUNT | Y2025_SALES_COUNT
상품1 | 101 | 102 | 103 | 104 | 105
상품2 | 201 | 202 | 203 | 204 | 205
상품3 | 301 | 302 | 303 | 304 | 305
SELECT PRODUCT_NAME AS 상품명, 연도, 판매량 FROM (
SELECT * FROM PRODUCT_SALES
) UNPIVOT (
판매량 FOR 연도 IN (
Y2021_SALES_COUNT AS '2021년',
Y2022_SALES_COUNT AS '2022년',
Y2023_SALES_COUNT AS '2023년',
Y2024_SALES_COUNT AS '2024년',
Y2025_SALES_COUNT AS '2025년'
)
)
ORDER BY 상품명, 연도 ASC;
=> 상품명 | 연도 | 판매량
상품1 | 2021년 | 101
상품1 | 2022년 | 102
상품1 | 2023년 | 103
상품1 | 2024년 | 104
상품1 | 2025년 | 105
상품2 | 2021년 | 201
상품2 | 2022년 | 202
상품2 | 2023년 | 203
상품2 | 2024년 | 204
상품2 | 2025년 | 205
상품3 | 2021년 | 301
상품3 | 2022년 | 302
상품3 | 2023년 | 303
상품3 | 2024년 | 304
상품3 | 2025년 | 305
정규표현식
- 패턴에 기반하여 검색, 치환, 추출 등 문자열 처리 수행
매타 문자
- 문자 그 자신이 가진 의미가 아니라 다른 의미로 사용되는 문자
- 예) 표현식 ‘^’ 문자는 ‘^’ 문자를 나타내는 것이 아니라 입력 문자열의 시작을 의미
| 메타 문자 | 의미 | 예 |
| ₩ | 메타 문자를 리터럴 문자로 표시하거나 리터럴 문자와 결합하여 정해진 메타 문자를 표시 | ₩₩: ₩(리터럴 문자), ₩n: 줄바꿈(개행) |
| ^ | 개행으로 나뉜 문자열의 시작 지점 | ^the: the로 시작하는 문자열 |
| $ | 개행으로 나뉜 물자열의 끝 지점 | ing$: ing로 끝나는 문자열 |
| . | 임의의 한 문자(개행 문자는 제외) | a.c: abc, a-c, adc … |
| ? | 선행 문자 0 또는 1개 존재 | ok?: o, ok |
| * | 선행 문자 0개 이상 존재 | ok?: o, ok, okk, okkk … |
| + | 선행 문자 1개 이상 존재 | ok?: ok, okk, okkk … |
| | | 선택적 일치 | a|b: a, b |
| [ ] | 대괄호 안의 문자들 중 하나와 일치 | [abc]: a, b, c |
| [-] | 연속 문자의 범위를 지정 | [a-z]: a ~ z |
| [^] | 대괄호 안의 문자들을 제외한 나머지 문자들 중 하나와 일치 | [^abc]: d, e, f … |
| ( ) | 소괄호로 묶은 표현식을 한 단위로 취급 | (abc): abc |
리터럴 문자
- 문자 그 자체가 가진 의미 그대로 사용되는 문자
Oracle과 SQL Server의 정규식 지원 차이
Oracle
- Oracle 10g부터 정규표현식 함수 지원
| 정규표현식 함수 | 설명 |
| REGEXP_LIKE | 정규표현식을 사용한 LIKE 연산 |
| REGEXP_REPLACE | 정규표현식을 사용한 문자열 대체 |
| REGEXP_INSTR | 정규표현식을 사용한 문자열 검색 후 위치 반환 |
| REGEXP_SUBSTR | 정규표현식을 사용한 부분 문자열 반환 |
| REGEXP_COUNT | 정규표현식을 사용한 특정 패턴의 문자열 개수 반환 |
SQL Server
- PATINDEX 함수: 찾고자 하는 문자열을 검색 후 위치를 반환, 정규식은 아니지만 유사한 패턴 문자열 지원
- LIKE 연산자: PATINDEX의 패턴 문자열 지원
| 메타 문자 | 의미 | 예 |
| % | 0개 이상의 문자 | %a%: a가 포함되어 있는 문자열 모두 |
| _ | 임의의 한 문자 | a_c: abc, a-c, adc … |
| [ ] | 대괄호 안의 문자들 중 하나와 일치 | [abc]: a, b, c |
| [-] | 연속 문자의 범위를 지정 | [a-z]: a ~ z |
| [^] | 대괄호 안의 문자들을 제외한 나머지 문자들 중 하나와 일치 | [^abc]: d, e, f … |
반응형
'자격증' 카테고리의 다른 글
| SQLD - 5. 관리구문 (0) | 2025.05.30 |
|---|---|
| SQLD - 3. SQL 기본 및 활용 (1) | 2025.05.30 |
| SQLD - 2. 데이터 모델과 SQL (0) | 2025.05.26 |
| SQLD - 1. 데이터 모델링의 이해 (0) | 2025.05.26 |
| 정보처리기능사 - 요약본 이것만 외우면 됩니다. (1) | 2025.04.14 |