[SQLD] WHERE

Shy·2024년 5월 20일

SQLD

목록 보기
13/23

WHERE 조건절

WHERE 조건절은 SQL에서 데이터베이스 쿼리를 통해 특정 조건에 맞는 데이터를 필터링하기 위해 사용된다.

  • 기본 SQL 문장 구성: SELECT 절과 FROM 절만 사용하면 테이블의 모든 자료가 결과로 출력되어 필요하지 않은 데이터까지 포함될 수 있다.
  • WHERE 절 사용: 원하는 데이터를 검색하기 위해 WHERE 절을 사용하여 조건을 설정할 수 있다. 예를 들어, 특정 값과 일치하는 데이터나 특정 범위 내의 데이터를 검색할 수 있다.
  • 조인 조건: WHERE 절은 두 개 이상의 테이블을 조인하는 조건을 포함할 수도 있다.
  • 시스템 자원 효율성: WHERE 절을 사용하지 않으면 불필요한 데이터를 검색하게 되어 데이터베이스 서버의 시스템 자원(CPU, 메모리 등)을 과다하게 사용하게 된다. 이는 성능 저하를 초래할 수 있다.
  • FTS(Full Table Scan): 조건이 없는 WHERE 절을 사용하면 FTS가 발생할 수 있으며, 이는 대량의 데이터를 검색할 때 비효율적일 수 있다. 그러나 병렬 처리를 통해 FTS를 유용하게 사용하는 경우도 있다.
SELECT [DISTINCT/ALL] 칼럼명 [ALIAS명] FROM 테이블명 WHERE 조건식;
  • 조건식 구성 요소:
    • 칼럼명: 조건식의 좌측에 위치
    • 비교 연산자: =, >, <, >=, <=, <>
    • 값 또는 표현식: 조건식의 우측에 위치
    • 비교 칼럼명: 조인 시 사용

연산자의 종류

WHERE 절에서 조건식을 작성할 때 사용되는 연산자는 크게 세 가지 종류로 나뉜다.

  1. 비교 연산자
    • 기본 비교 연산자: =, >, <, >=, <=, <>
    • 부정 비교 연산자: !=, <>
  2. SQL 연산자
    • 기본 SQL 연산자: BETWEEN ... AND ..., IN (...), LIKE, IS NULL
    • 부정 SQL 연산자: NOT BETWEEN ... AND ..., NOT IN (...), NOT LIKE, IS NOT NULL
  3. 논리 연산자
    • AND, OR, NOT

1️⃣ 연산자 우선순위

  • 괄호: 괄호로 묶은 연산이 가장 먼저 처리된다.
  • 부정 연산자(NOT): NOT 연산자가 우선적으로 처리된다.
  • 비교 연산자: =, >, >=, <, <= 등이 처리된다.
  • SQL 비교 연산자: BETWEEN ... AND ..., IN (...), LIKE, IS NULL 등이 처리된다.
  • 논리 연산자: AND가 OR보다 우선적으로 처리된다.

2️⃣ 조건 예시

삼성블루윙즈 또는 전남드래곤즈 소속이며, 포지션이 미드필더(MF)이고, 키가 170cm 이상 180cm 이하인 선수들의 이름과 포지션, 백넘버를 검색하는 경우를 sql문으로 작성하면 다음과 같다.

SELECT 이름, 포지션, 백넘버 
FROM 선수 
WHERE (소속팀 = '삼성블루윙즈' OR 소속팀 = '전남드래곤즈') 
  AND 포지션 = 'MF' 
  ANDBETWEEN 170 AND 180;

위 쿼리는 다양한 연산자를 사용하여 조건을 조합한 예시이다. 괄호를 사용하여 논리 연산자의 우선순위를 명확히 함으로써 원하는 결과를 정확하게 얻을 수 있다.

비교 연산자

비교 연산자는 SQL에서 데이터를 필터링하는 데 사용되는 중요한 도구이다. 다양한 조건을 구성하여 데이터를 세부적으로 검색할 수 있다. 비교 연산자의 종류는 다음과 같다.

비교 연산자의 종류

  • = : 두 값이 같은지 비교
  • <> 또는 != : 두 값이 다른지 비교
  • > : 왼쪽 값이 오른쪽 값보다 큰지 비교
  • < : 왼쪽 값이 오른쪽 값보다 작은지 비교
  • >= : 왼쪽 값이 오른쪽 값보다 크거나 같은지 비교
  • <= : 왼쪽 값이 오른쪽 값보다 작거나 같은지 비교

예시를 통한 비교 연산자 사용

예제1

다음은 소속팀, 포지션, 키와 같은 칼럼을 특정 값과 비교하는 예이다.

  1. 소속팀이 삼성블루윙즈(K02)인 선수
  2. 소속팀이 전남드래곤즈(K07)인 선수
  3. 포지션이 미드필더(MF)인 선수
  4. 키가 170cm 이상인 선수
  5. 키가 180cm 이하인 선수

이를 SQL문으로 작성하면 다음과 같다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE TEAM_ID = 'K02' 
   OR TEAM_ID = 'K07' 
   AND POSITION = 'MF' 
   AND HEIGHT >= 170 
   AND HEIGHT <= 180;

예제2

소속팀이 삼성블루윙즈인 선수를 검색하는 예제이다.

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

실행 결과는 다음과 같다.

선수이름    포지션    백넘버    키
--------  ----    ----    ----
김성환       DF      5      183
가비        MF     10      177
강대희       MF     26      174
고종수       MF     22      176
고창현       MF      4      175
정준        MF     44      170
정진우       DF      7      179
데니스       FW     11      176
서정원       FW     14      173
...
(49개의 행이 선택됨)

예제3

포지션이 미드필더(MF)인 선수를 검색하는 예제이다.

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

실행 결과는 다음과 같다.

선수이름    포지션  백넘버      키
--------  ----  ----      ----
가비        MF     10      177
강대희       MF     26      174
고종수       MF     22      176
고창현       MF      8      170
정기범       MF     28      173
정동현       MF     25      175
정두현       MF      4      175
정준        MF     44      170
오규찬       MF     24      178
윤원일       MF     45      176
장성철       MF     27      176
...
(162개의 행이 선택됨)

예제4

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

실행 결과는 다음과 같다.

선수이름     포지션  백넘버     키
--------  ----   ----     ----
김성환       DF      5      183
가비        MF     10      177
강대희       MF     26      174
고종수       MF     22      176
고창현       MF      8      170
정기범       MF     28      173
정동현       MF     25      175
정두현       MF      4      175
정준        MF     44      170
정진우       DF      7      179
데니스       FW     11      176
...
(439개의 행이 선택됨)

문자형 비교

문자형 칼럼을 비교할 때는 작은따옴표(’ ’)나 큰따옴표(” “)를 사용해야 한다.

  • WHERE TEAM_ID = 'K02'
  • WHERE POSITION = 'MF'

숫자형 칼럼을 비교할 때는 인용부호가 필요 없다.

  • WHERE HEIGHT >= 170

숫자형 칼럼과 문자열 비교도 가능하다. 문자열이 숫자로 변환될 수 있다면 내부적으로 변환이 이루어진다.

  • WHERE HEIGHT >= '170'

SQL 연산자

SQL 연산자는 SQL 문장에서 데이터 조작 및 검색을 위해 기본적으로 예약된 연산자이다. 주요 SQL 연산자에는 다음과 같은 네 가지 종류가 있다.

  1. IN (list) 연산자
  2. LIKE 연산자
  3. BETWEEN a AND b 연산자
  4. IS NULL 연산자

각 연산자는 다양한 데이터 타입에 대해 적용할 수 있으며, 조건에 맞는 데이터를 쉽게 검색할 수 있도록 도와준다.

1️⃣ IN (list) 연산자

IN 연산자는 지정된 값의 목록 중 하나와 일치하는 데이터를 검색할 때 사용된다.

다음은 소속팀 코드와 관련된 IN (list) 형태의 SQL 비교 연산자 사용하는 예제이다.

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

다음은 실행 결과이다.

선수이름   포지션    백넘버     키
-------- ----    ----    ---
데니스     FW      11      176
서정원     FW      14      173
손대호     DF      17      186
...
(100개의 행이 선택됨)

다중 리스트 IN 연산자 사용 예제는 다음과 같다.

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

실행 결과는 다음과 같다.

ENAME  JOB      DEPTNO
------ -------- ------
JONES  MANAGER  20
JAMES  CLERK    30

다중 리스트를 이용한 IN 연산자는 SQL 문장을 간결하게 하면서도 성능 향상에 도움을 줄 수 있는 유용한 연산자이다.

2️⃣ LIKE 연산자

LIKE 연산자는 특정 패턴과 일치하는 문자열을 검색하는 데 사용된다. 와일드카드 문자를 이용하여 다양한 패턴을 지정할 수 있다.

  • %: 0개 이상의 문자를 대체
  • _: 1개의 문자를 대체

예제1

다음은 포지션이 ‘MF’인 선수를 검색하는 SQL문이다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE POSITION LIKE 'MF';
-- 실행 결과
선수이름    포지션    백넘버    키
--------  ----    ----    ---
가비       MF      10      177
강대희      MF      26      174
...
(162개의 행이 선택됨)

예제2

“장”씨 성을 가진 선수를 검색하는 예제이다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE PLAYER_NAME LIKE '장%';
-- 실행 결과
선수이름  포지션  백넘버  키
--------  ----    ----    ---
장성철     MF      27      176
장윤정     DF      17      173
...
(13개의 행이 선택됨)

3️⃣ BETWEEN a AND b 연산자

BETWEEN 연산자는 지정된 범위 내의 값을 검색할 때 사용된다. a와 b 값을 포함한 범위에서 데이터를 검색한다.

예제1

키가 170cm 이상 180cm 이하인 선수를 검색하는 예제이다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE HEIGHT BETWEEN 170 AND 180;
-- 실행 결과
선수이름    포지션  백넘버      키
--------  ----    ----    ----
장철우      DF      7       172
홍광철      DF      4       172
...
(259개의 행이 선택됨)

4️⃣ IS NULL 연산자

IS NULL 연산자는 특정 칼럼의 값이 NULL인지를 확인할 때 사용된다. NULL은 값이 존재하지 않음을 나타내며, 일반 비교 연산자로는 비교할 수 없다.

예제1

POSITION 칼럼이 NULL인 선수를 검색하는 예제이다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, TEAM_ID 
FROM PLAYER 
WHERE POSITION IS NULL;
선수이름  포지션  TEAM_ID
--------  ----    -------
정학범            K08
안익수            K08
차상광            K08
...
(3개의 행이 선택됨)
  • IN 연산자: 지정된 값 목록 중 하나와 일치하는 데이터를 검색.
  • LIKE 연산자: 특정 패턴과 일치하는 문자열을 검색. 와일드카드(%_)를 사용하여 패턴 지정.
  • BETWEEN 연산자: 지정된 범위 내의 값을 검색. a와 b 값을 포함.
  • IS NULL 연산자: 특정 칼럼의 값이 NULL인지 확인. 일반 비교 연산자로는 NULL을 비교할 수 없음.

5️⃣ 논리 연산자

논리 연산자는 비교 연산자나 SQL 비교 연산자로 구성된 여러 조건을 논리적으로 연결하기 위해 사용된다. 이를 통해 복잡한 조건을 조합하여 보다 정밀한 데이터 검색이 가능하다. 주요 논리 연산자는 다음과 같다.

  • AND: 두 조건이 모두 참일 때 결과가 참
  • OR: 두 조건 중 하나라도 참일 때 결과가 참
  • NOT: 조건이 거짓일 때 결과가 참

예제1

소속이 삼성블루윙즈이고 키가 170cm 이상인 선수들을 조회하는 SQL 문장은 다음과 같다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE TEAM_ID = 'K02' AND HEIGHT >= 170;
-- 실행 결과
선수이름    포지션  백넘버     키
--------  ----   ----    ---
김반코비    MF      47      185
김선우      FW     33      174
김여성      MF     36      179
...
(45개의 행이 선택됨)

예제2

소속이 삼성블루윙즈(K02) 또는 전남드래곤즈(K07)이며 포지션이 미드필더(MF)인 선수들을 조회하는 SQL 문장은 다음과 같다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE TEAM_ID IN ('K02', 'K07') AND POSITION = 'MF';
선수이름    포지션  백넘버      키
--------  ----    ----    ---
노병준      MF      22      177
최종우      MF      43      176
조진원      MF      9       176
...
(40개의 행이 선택됨)

논리 연산자와 조건의 우선순위

논리 연산자의 우선순위는 다음과 같다.

  1. 괄호 (())
  2. NOT
  3. AND
  4. OR

이 우선순위를 염두에 두지 않으면 의도하지 않은 결과가 나올 수 있다. 예를 들어, 아래 SQL 문장에서 원하는 결과가 나오지 않는 이유는 괄호의 부재 때문이다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE TEAM_ID = 'K02' OR TEAM_ID = 'K07' AND POSITION = 'MF' AND HEIGHT >= 170 AND HEIGHT <= 180;

이 SQL 문장은 다음과 같은 방식으로 해석된다

  1. AND 연산자는 OR 연산자보다 우선순위가 높다.
  2. 따라서 SQL 문장은 TEAM_ID = 'K07' AND POSITION = 'MF' AND HEIGHT >= 170 AND HEIGHT <= 180 부분이 먼저 처리된다.
  3. 그 결과 TEAM_ID = 'K02'TEAM_ID = 'K07' AND POSITION = 'MF' AND HEIGHT >= 170 AND HEIGHT <= 180 두 조건이 OR 연산자로 연결된다.
선수이름     포지션  백넘버     키
--------  ----    ----    ---
김성환      DF      5       183
...
(66개의 행이 선택됨)

위 결과는 포지션이 DF나 FW인 선수도 포함되었기 때문이다. 이는 OR 연산자가 AND보다 낮은 우선순위를 가지기 때문에 발생한 문제이다. 괄호를 사용하여 우선순위를 명확히 하면 다음과 같이 수정할 수 있다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE (TEAM_ID = 'K02' OR TEAM_ID = 'K07') AND POSITION = 'MF' AND HEIGHT >= 170 AND HEIGHT <= 180;
-- 실행 결과
선수이름    포지션    백넘버    키
--------  ----    ----    ---
가비       MF      10      177
강대희      MF      26      174
고종수      MF      22      176
...
(33개의 행이 선택됨)

다양한 연산자를 조합한 예

IN (list)와 BETWEEN a AND b 연산자를 사용하여 같은 결과를 출력하는 SQL 문장은 다음과 같다.

SELECT PLAYER_NAME 선수이름, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE TEAM_ID IN ('K02', 'K07') AND POSITION = 'MF' AND HEIGHT BETWEEN 170 AND 180;
선수이름    포지션    백넘버    키
--------  ----    ----    ---
가비       MF      10      177
강대희     MF      26      174
고종수     MF      22      176
...
(33개의 행이 선택됨)

  • AND 연산자: 두 조건이 모두 참일 때 사용.
  • OR 연산자: 두 조건 중 하나라도 참일 때 사용.
  • NOT 연산자: 조건이 거짓일 때 사용.
  • 우선순위: 괄호를 사용하여 명확히 해야 함.
  • IN 연산자와 BETWEEN 연산자: 다중 조건을 효율적으로 작성할 수 있는 방법을 제공.

부정 연산자

부정 연산자는 비교 연산자나 SQL 비교 연산자에 대해 부정 논리 연산자 또는 부정 SQL 연산자를 사용하여 조건을 부정할 때 사용된다. 부정 연산자는 특정 조건을 만족하지 않는 데이터를 검색할 때 유용하다.

1️⃣ 부정 연산자의 종류

  • NOT: 조건을 부정
  • <> 또는 !=: 값이 같지 않음을 의미
  • NOT IN: 목록에 포함되지 않음을 의미
  • NOT LIKE: 특정 패턴과 일치하지 않음을 의미
  • NOT BETWEEN: 범위에 포함되지 않음을 의미
  • IS NOT NULL: 값이 NULL이 아님을 의미

예제1

삼성블루윙즈 소속인 선수 중 포지션이 미드필더(MF)가 아니고, 키가 175cm 이상 185cm 이하가 아닌 선수들의 자료를 찾는 SQL 문장은 다음과 같다.

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;
-- 실행 결과
선수이름    포지션    백넘버    키
--------  ----    ----    ---
서정원      FW      14      173
손대호      DF      17      186
김선우      FW      33      174
...
(8개의 행이 선택됨)

예제2

국적(NATION) 칼럼이 NULL이 아닌 선수의 국적을 표시하는 SQL 문장은 다음과 같다.

SELECT PLAYER_NAME 선수이름, NATION 국적 
FROM PLAYER 
WHERE NATION IS NOT NULL;
-- 실행 결과
선수이름  국적
--------  ------
가비       루마니아
데니스     러시아
...
(27개의 행이 선택됨)

ROWNUM과 TOP 사용

1️⃣ ROWNUM (Oracle)

ROWNUM은 Oracle에서 각 행에 대해 임시로 부여되는 일련번호이다. 이를 사용하여 SQL 처리 결과 집합에서 원하는 만큼의 행만 가져올 수 있다.

한 건의 행만 가져오기

SELECT PLAYER_NAME 
FROM PLAYER 
WHERE ROWNUM = 1;

또는

SELECT PLAYER_NAME 
FROM PLAYER 
WHERE ROWNUM <= 1;

또는

SELECT PLAYER_NAME 
FROM PLAYER 
WHERE ROWNUM < 2;

N건의 행만 가져오기

SELECT PLAYER_NAME 
FROM PLAYER 
WHERE ROWNUM <= N;

또는

SELECT PLAYER_NAME 
FROM PLAYER 
WHERE ROWNUM < N+1;

추가 용도

테이블 내 고유한 키나 인덱스 값을 만들기 위해 사용할 수 있다.

예를 들어, 아래와 같이 테이블을 만들어보자.

CREATE TABLE MY_TABLE (
  ID NUMBER,
  COLUMN1 NUMBER
);

INSERT INTO MY_TABLE (ID) VALUES (1);
INSERT INTO MY_TABLE (ID) VALUES (2);
INSERT INTO MY_TABLE (ID) VALUES (3);
INSERT INTO MY_TABLE (ID) VALUES (4);

그러면 아래와 같은 테이블이 만들어질 것이다.

IDCOLUMN1
1NULL
2NULL
3NULL
4NULL

이때, 고유한 키나 인덱스 값을 만들기 위해 아래와 같이 UPDATE를 실행해보자.

UPDATE MY_TABLE 
SET COLUMN1 = ROWNUM;

그러면 아래와 같은 결과가 나온다.

IDCOLUMN1
11
22
33
44

2️⃣ TOP 절 (SQL Server)

TOP 절은 SQL Server에서 결과 집합으로 출력되는 행의 수를 제한할 수 있다.

TOP (Expression) [PERCENT] [WITH TIES]
  • Expression: 반환할 행의 수를 지정하는 숫자.
  • PERCENT: 쿼리 결과 집합에서 처음 Expression의 행만 반환.
  • WITH TIES: ORDER BY 절이 지정된 경우에만 사용하며, TOP N(PERCENT)의 마지막 행과 같은 값이 있는 경우 추가 행이 출력되도록 지정.

1. 한 건의 행만 가져오기

SELECT TOP(1) PLAYER_NAME 
FROM PLAYER;

2. N 건의 행 가져오기

SELECT TOP(N) PLAYER_NAME 
FROM PLAYER;

3. 예제

-- 역순의 키로, 상위 10명만 가져오는 SQL문
SELECT TOP(10) PLAYER_NAME 
FROM PLAYER 
ORDER BY HEIGHT DESC;

3️⃣ ROWNUM과 TOP의 차이점

  • ROWNUMTOPORDER BY 절이 사용되지 않는 경우 기능이 유사하다.
  • ORDER BY 절이 사용될 때는 차이가 발생한다. ORDER BY 절과 함께 사용할 때의 차이점은 ORDER BY 절에서 자세히 설명한다.
  • 부정 연산자: 조건을 부정하는 데 사용. 예: NOT, <>, !=, NOT IN, NOT LIKE, NOT BETWEEN, IS NOT NULL.
  • ROWNUM (Oracle): 결과 집합의 각 행에 임시 번호를 부여하여 행 수를 제한.
  • TOP 절 (SQL Server): 결과 집합의 행 수를 제한.
profile
신입사원...

0개의 댓글