
안녕하세요, 성조입니다.
PostgreSQL의 WHERE 문과 조건 연산자 정리에 대해 가볍게 포스팅으로 정리하는 시간을 가져보려 해요.
WHERE이란?
테이블은 수많은 행(Row)으로 이뤄져 있다. 이 수많은 행(Row)에서 주오진 조건이 참(Ture)인 행만 통과시키고, 거짓(False)이거나 알 수 없는(NULL) 행들을 필터 역할을 한다.
SQL 쿼리 실행 순서의 이해
쿼리가 실행되는 순서는 작성했던 순서와 다르게 동작한다.
1. FROM -> 어떤 테이블에서 데이터를 가져올지 확인한다. (영역)
2. WHERE -> 테이블의 모든 행을 조건에 따라 필터링한다. -> 이번 포스팅에서 다루는 내용으로 데이터의 양이 가시적으로 줄어든다.) (if와 같은 조건)
3. SELECT -> 필터링을 통과한 행들 중에서 화면에 보여줄 열(Column)만 선택해준다. (View에 조건)
기본 문법
SELECT 가져올_컬럼_이름
FROM 테이블_이름
WHERE 조건식;
WHERE 절은 반드시 FROM 절 바로 다음에 나와야 하며, 그룹화(GROUP BY)나 정렬(ORDER BY)보다 먼저 작성되어야 한다.
WEHER의 조건 사용 예시
| 조건 | 예시 |
| = '같다'라는 조건이다 | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE age = 50; (나이가 50인 데이터를) |
| != <> ^=는 PostgreSQL에서 미지원하며, '아니다'의 의미가 되는 조건이다 |
SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE age != 50; (나이가 50이 아니면) |
| >, < | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE age > 50; (나이가 50 초과) |
| >=, <= | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE age >= 50; (나이가 50 이상) |
| IN | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE age IN (50, 60); (나이가 50인지 60인지 둘 중 하나로 포함되는 것인가를 판별) |
| LIKE | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE name LIKE '김%'; (김으로 시작하는 모든 데이터를 조회) |
| BETWEEN | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE age BETEEN 50 AND 60; (나이가 50 이상 60이하의 데이터 조회) |
| IS NULL | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE IS NULL address; (주소지 값이 빈 경우 알 수 없는 데이터들의 값들을 조회.) |
| AND | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE name LIKE '김%'; AND company = '삼%' (이름이 김으로 시작하면서(AND) 회사 명이 삼으로 시작하는 데이터를 조회) |
| OR | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE name LIKE '김%'; OR company = '삼%' (이름이 김으로 시작하거나,(OR) 회사 명이 삼으로 시작하는 데이터를 조회) |
| NOT | SELECT [테이블 안에 고를 열 or *] FROM [테이블] WHERE NOT age > 30; (나이가 30이 초과되지 않는 데이터를 조회 -> 평소에 NOT IN, NOT LIKE, NOT BETWEEN 기능들을 기반으로 사용한다.) |
PostgreSQL의 연산자 우선순위
| 우선순위 | 분류 | 기호 및 키워드 | 설명 |
| 1 | 스키마/객체 접근 | . | 테이블명.컬럼명 처럼 특정 객체에 접근하기 위한 구분자로 가장 먼저 해석된다. |
| 2 | 타입 캐스팅 | :: | age::integer 와 같이 데이터의 형변환을 산술이나 비교 이전에 가장 먼저 확정 짓는다. |
| 3 | 배열 접근 | [ ] | 배열 형태의 데이터에서 특정 인덱스의 요소를 선택하는 작업이 수행된다. |
| 4 | 단항 연산자 | +, - | 양수와 음수를 나타내는 부호 연산이 처리된다. |
| 5 | 정렬 지정 | COLLATE | 문자열의 대소문자 구분이나 국가별 정렬 방식(Collation)을 세팅된다. |
| 6 | 시간대 변환 | AT | AT TIME ZONE 등 날짜/시간 데이터의 타임존(Timezone) 변환을 처리한다. |
| 7 | 지수 연산 | ^ | 거듭제곱(지수) 연산이 산술 연산 중 가장 먼저 실행된다. |
| 8 | 산술 (곱/나눔/나머지) | *, /, % | 수학과 동일하게 곱하기, 나누기, 나머지 구하기 연산을 수행한다. |
| 9 | 산술 (덧/뺄셈) | +, - | 더하기, 빼기 연산을 수행한다. |
| 10 | 기타 / 사용자 정의 | (기타 모든 기호) | 기본 내장 기호 외에 JSON, 배열 처리 등에 쓰이는 특수 연산자(@>, ->> 등)나 사용자 정의 기호가 이 단계에서 처리된다. |
| 11 | 패턴 및 범위 조건 | BETWEEN, IN, LIKE, ILIKE, SIMILAR | 문자열 패턴 매칭이나 리스트/범위 포함 여부를 확인하는 특수 조건들이 일반 비교보다 먼저 평가된다. |
| 12 | 기본 비교 조건 | <, >, =, <=, >=, <> | 값의 크기를 비교하거나 일치하는지 확인하는 기본적인 수학적 비교 기호이다. 크거나 작거나 초과하거나 미만이거나 이상 이하 이런 데이터들이 기반이 된다. |
| 13 | 상태 확인 조건 | IS, ISNULL, NOTNULL | 데이터가 비어있는지(IS NULL) 판별하거나 IS TRUE 등 데이터의 상태를 묻는 조건이다. |
| 14 | 논리 부정 | NOT | 11~13순위에서 만들어진 조건의 참/거짓 결과를 반대로 뒤집는다. |
| 15 | 논리 교집합 | AND | 두 조건이 모두 참인지 확인하며, OR보다 무조건 먼저 실행된다. |
| 16 | 논리 합집합 | OR | 여러 조건 중 하나라도 참인지 확인하며, 쿼리 평가의 가장 마지막에 최종 결과를 결정짓는다. |
4번 우선 순위와 9번 우선 순위의 차이 정리.
1. 단항 연산자 (Unary Operator) -> 우선 순위 높음
- 데이터 1개에만 딱 붙어서, 그 숫자가 양수인지 음수인지 부호를 결정하는 이름표 역할을 하는 경우를 의미한다.
- -5, +100 음수 양수 이런 구조를 의미함.
2. 산술 연산자(Binary Operator)
- 데이터 2개 사이에서 실제로 '더하기'나 '빼기' 계산을 수행하는 경우를 의미.
- '10 + 1', '20 - 5' 같은 산술 연산자를 의미한다.
ORCLE의 연산자 우선순위
오라클 데이터베이스는 연산자 1~3번이 우선순위로 들어가고, 조건 연산자가 4~8번으로 들어간다.
| 우선순위 | 분류 | 기호 및 키워드 | 설명 |
| 1 | 단항 및 계층 연산자 | +, - (단항), PRIOR, CONNECT_BY_ROOT, COLLATE | 양수/음수를 나타내는 단항 부호와, 오라클 특유의 계층형 쿼리(트리 구조) 탐색에 쓰이는 연산자가 가장 먼저 실행된다. |
| 2 | 산술 (곱셈/나눗셈) | *, / | 일반적인 수학 사칙연산 규칙과 동일하게 곱하기와 나누기를 먼저 처리한다. |
| 3 | 산술 (덧/뺄셈), 문자열 결합 | +, - (이항), || | 더하기, 빼기와 함께 문자열을 이어 붙이는 || 연산자가 이 단계에서 처리된다. (여기까지가 일반 데이터 연산이다.) |
| 4 | 기본 비교 조건 | =, !=, <>, <, >, <=, >= | 값의 크기나 일치 여부를 비교하는 가장 기본적인 수학적 비교 기호들이 먼저 평가된다. |
| 5 | 특수 비교 조건 | IS [NOT] NULL, LIKE, [NOT] BETWEEN, [NOT] IN, EXISTS, IS OF type | 단순 기호 비교가 끝난 후, 패턴 매칭(LIKE)이나 포함 여부(IN, BETWEEN), 데이터 유무(NULL, EXISTS) 등 오라클의 특수 내장 조건들이 실행됩니다. |
| 6 | 논리 부정 | NOT | 4, 5순위에서 만들어진 조건의 참/거짓 결과를 반대로 뒤집는(부정하는) 작업이 진행된다. |
| 7 | 논리 교집합 | AND | 두 조건이 모두 참인지 확인하는 AND가 OR보다 먼저 평가한다. |
| 8 | 논리 합집합 | OR | 두 조건 중 하나라도 참인지 확인하는 OR가 가장 마지막으로 쿼리 전체의 결과를 결정짓는다. |
MYSQL의 연산자 우선순위
| 우선순위 | 분류 | 기호 및 키워드 | 설명 |
| 1 | 시간 간격 연산 | INTERVAL | 날짜나 시간 데이터에 간격(예: 1일, 2시간)을 더하거나 뺄 때 쓰는 키워드가 가장 먼저 평가된다. |
| 2 | 타입/정렬 변환 | BINARY, COLLATE | 문자열을 바이너리(이진) 데이터로 변환하거나 정렬 방식(Collation)을 지정한다. |
| 3 | 논리 부정 (기호) | ! | C언어 스타일의 논리 부정 기호다. 13순위의 NOT 키워드보다 훨씬 먼저 우선적으로 실행된다. |
| 4 | 단항 / 비트 반전 | - (단항), ~ | 값 1개에 붙는 음수 부호(-)와 비트를 뒤집는(~) 연산이다. |
| 5 | 비트 배타적 논리합 | ^ | 비트(Bit) 단위의 XOR 연산을 수행한다. (PostgreSQL에서는 거듭제곱이었지만, MySQL에서는 비트 연산을 통해 배타적 논리합 기능을 제공한다.) |
| 6 | 산술 (곱/나눔/나머지) | *, /, DIV, %, MOD | 곱하기, 나누기, 몫(DIV), 나머지(%, MOD) 등 산술 연산을 수행한다. |
| 7 | 산술 (덧/뺄셈) | +, - (이항) | 값 2개 사이에서 더하기, 빼기 연산을 수행한다. (단항 부호보다 나중에 실행된다.) |
| 8 | 비트 시프트 | <<, >> | 비트를 좌우로 이동시키는 연산. |
| 9 | 비트 논리곱 | & | 비트 단위의 AND 연산 |
| 10 | 비트 논리합 | | | 비트 단위의 OR 연산 |
| 11 | 비교 및 패턴 매칭 | =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN | 값의 크기 비교, 패턴 매칭(정규식 REGEXP 포함), NULL 안전 비교(<=>) 등 모든 조건 비교가 동급으로 처리된다. |
| 12 | 범위 및 조건 분기 | BETWEEN, CASE, WHEN, THEN, ELSE | 범위 검색(BETWEEN)과 데이터를 조건에 따라 변환하는 CASE WHEN 구문이 평가된다. |
| 13 | 논리 부정 (키워드) | NOT | 일반적인 논리 부정 키워드이다. (3순위의 ! 기호와 역할은 같지만 실행 순서가 한참 뒤로 배정받는다.) |
| 14 | 논리 교집합 | AND, && | 두 조건이 모두 참인지 확인. OR보다 항상 먼저 평가. |
| 15 | 논리 배타적 합집합 | XOR | 두 조건 중 하나만 참일 때 통과한다. (MySQL 특화 논리 연산자) |
| 16 | 논리 합집합 | OR, || | 여러 조건 중 하나라도 참인지 확인한다. (MySQL에서 ||는 문자열 결합이 아니라 OR 연산자로 연산들을 작동시킨다) |
| 17 | 할당 연산자 | =, := | 변수에 값을 대입하는 연산(예: SET @var := 1)으로 쿼리 실행의 가장 마지막에 처리된다. |
이렇게 각 데이터베이스 엔진들은 우선 순위를 다르게 가져간다.
감사합니다.
다음 포스팅에서 뵙겠습니다.
'Database' 카테고리의 다른 글
| [PostgreSQL] 포스트그레스큐엘 기초 정리 (0) | 2026.03.08 |
|---|---|
| [Mongo] Mongo Database란? (0) | 2022.12.08 |
| [Database] [Oracle] Oracle 19C 버전 설치하기 (0) | 2022.07.17 |
| [Database] 이상 현상(Anomaly)이란? (0) | 2022.04.29 |
| [Database] 정규화(Normalization)란? (0) | 2022.04.28 |