Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

걸음마부터 달리기

DB- Where절 본문

카테고리 없음

DB- Where절

성추 2024. 7. 27. 00:28

자료를 검색할 때 SELECT 절과 FROM 절만을 사용하여 기본적인 SQL 문장을 구성한다면, 테이블에 있는 모든 자료들이 결과로 출력되어 실제로 원하는 자 료를 확인하기 어려울 수 있다. 사용자들은 자신이 원하는 자료만을 검색하기 위해서 SQL 문장에 WHERE 절을 이용하여 자료들에 대하여 제한할 수 있다

Where절에는 크게

두 개 이상의 테이블에 대한 조인 조건을 기술하거나 결과를 제한하기 위한 조건을 기술할 수도 있다.

 

SELECT [DISTINCT/ALL] 칼럼명 [ALIAS명]
FROM 테이블명
WHERE 조건식

조건식은 
[칼럼명] [연산자] [문자,숫자,표현식 | 비교칼럼명(JOIN시)]
이다.
이때 연산자는 SQL연산자, 비교연산자가 가능하고 논리연산자는 조건식과 조건식을 묶을때 사용한다.

 

연산자 종류:

WHERE절의 연산자 3가지 - 비교,SQL,논리 연산자

 

이러한 조건식에서 조심해야될 것은 이게 문자형타입인지 NUMERIC 같은 숫자형 타입인지를 봐야된다. 

문자형 타입은 인용부호 ' 혹은 "를 붙여서 조건식 처리를 해줘야된다.

그럼 SQL에서는 문자열끼리 비교연산자는 어떻게 연산할까?

위와 같다. 앞 게시물에서 CHAR와 VARCHAR의 차이점을 알아보았었다. 

CHAR는 고정이기에 서로 길이가 다를경우 서로 길이를 맞춰줘야한다. 따라서 길이가 작은 쪽을 큰쪽으로 맞추면서 빈칸을 넣게 된다. 서로 다른 문자가 나올때까지 비교하고 문자가 처음 달라지기 시작한 순간에 양쪽의 문자값에 따라 크기를 정한다.

VARCHAR같은 경우는 애초에 가변길이니까 공백 넣지 않고 그대로 비교한다. 만약 길이도 다르고 문자열도 다르다면 처음 달라지는 그 순간의 문자 크기로 비교하면 되는거고

문자열은 같은데 길이가 서로 다르면 길이가 더 긴쪽을 큰것으로 판단한다.

만약 문자열,길이 모두 같으면 그건 같다고 판단한다.

만약 상수와 문자열의 비교이면 상수를 문자열로 바꾸고 비교하는데 변수쪽이 CHAR이면 CHAR을 따라가고 VARCHAR이면 VARCHAR 비교 방법을 따라가면 된다. 

중요한건 위의 방법은 변수가 문자열일때의 비교방법이다. 

 

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

위의 SQL을 봐보자. 이때의 조건식은 HEIGHT가 문자열이 아닌 NUMERIC타입이기에 숫자형이다. 따라서 원래 하던대로 숫자형과 170이라는 숫자형을 비교하면 된다. 근데 반대로

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

이면 어떨까?

'170'은 문자열 , HEIGHT는 숫자형이다. 변수 HEIGHT는 문자열이 아니기에 앞에서 논했던 방법은 통하지 않는다.

이때는 숫자 유형의 칼럼의 경우 숫자로 변환이 가능한 문자열과 비교되면 상대 타입을 숫자타입으로 바꾸어 비교한다.

따라서 '170'을 숫자타입인 170으로 바꾸고 숫자형 변수인 HEIGHT와의 비교를 수행한다.

 

SQL 연산자

SQL연산자는 SQL 문장에서 사용하도록 기본적으로 예약되어 있는 연산자이다. 

 

IN 연산자는 다중리스트를 지원하는데

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

와 같이 리스트 여러개가 매핑될 수도 있다.

각각의 리스트는 JOB과 DEPTNO가 동시에 만족해야하고 이는

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

와는 다르다. 이는 (MANAGER 이거나 CLERK) 이면서 (20이거나 30) 을 의미한다. 

 

LIKE연산자는 = 의 비교연산자와는 다르다.

둘다 "~와 같다" 이지만 LIKE연산자는 와일드카드를 사용하여 조건식의 문자열 값을 유연하게 제공할 수 있는 반면 

= 의 비교연산자는 문자열을 유연하게 제공하지 못한다.

예를 들어 장씨 성을 가진 데이터를 선택하고 싶으면

LIKE '장%' 라고 하면 된다.

 

IS NULL연산자는 NULL값을 위한 특수 연산이라고 생각하면 편하다.

NULL은 기본적으로 연산과 비교가 불가능하다. 

따라서 NULL과 비교연산하면 FALSE가 나오고 NULL과 산술연산을 하면 그대로 NULL이다.

그러므로 NULL을 쓰는 조건식에서는 특수한 연산이 필요한 것이다.

그것이 바로 IS NULL  , IS NOT NULL 이다.

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

이거는 무엇이 문제일까... 

얼핏보면 문제없지만 = 의 비교연산이 문제이다. NULL과의 = 연산은 FALSE이기에 해당 SQL은 ERROR가 없지만 알맞지는 않은 SQL문이다.

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

로 해야 맞다.

 

논리연산자는 여러개의 조건식을 논리적으로 연결시키기 위해서 사용되는 연산이다.

간단하니 스킵하겠지만 조심해야할 부분이 있다.

논리연산자도 우선순위가 존재한다.

NOT AND OR 순서이기에 

이 둘은 서로 다르다. 애매하거나 명확하게 하기 위해서 ()를 써주자.

 

 

BETWEEN 과 IN 연산자 , OR과 AND 연산자의 동일치

재밌는건

HEIGHT BETWEEN 170 AND 180
HEIGHT >=170 AND HEIGHT <=180
은 결과도 같고 내부적으로 처리하는 방법도 같다.

마찬가지로
TEAM_ID = 'K02' OR TEAM_ID = 'K07' 과
TEAM_ID IN ('K02','K07') 
도 같다.

 

부정연산자는 비교연산자, SQL연산자의 부정표현으로 우리가 생각하는 부정과 일치한다. 스킵한다.

 

ROWNUM

ROWNUM은 칼럼과 비슷한 성격의 Pseudo Column으로서 SQL 처리 결과 집합의 각 행에 대해 임시로 부여되는 일련번호이다. 임시이기에  Pseudo Column이다. 주로 원하는 개수만큼의 행만 가지고 오고싶을때 WHERE절에서 행의 개수제한을 위해 사용한다.

SELECT PLAYER_NAME FROM PLAYER WHERE ROWNUM = 1; 
SELECT PLAYER_NAME FROM PLAYER WHERE ROWNUM <= 1;
SELECT PLAYER_NAME FROM PLAYER WHERE ROWNUM < 2;

SELECT PLAYER_NAME FROM PLAYER WHERE ROWNUM < N;

당연히 예상했듯이 이걸로 테이블내의 고유한 키나 인덱스 값을 칼럼에 지정할 수도 있다.

UPDATE MY_TABLE SET COLUMN1 = ROWNUM;

COLUMN1의 칼럼값들이 ROWNUM으로 1씩 증가하는 순차번호가 된다.