반응형
  1. 서브쿼리

서브쿼리는 SELECT 명령에 의한 데이터 질의로, 상부가 아닌 하부의 부수적 질의를 의미합니다.

서브쿼리를 지정하는 방법은 간단하게 SELECT 쿼리를 괄호로 묶어서 SELECT / FROM / WHERE 구 등에서 사용할 수 있습니다.

  1. 스칼라 값

서브쿼리를 다른 구에서 사용하는 것을 설명하기전에 스칼라 값이라는 것에 대해 설명해 보겠습니다.

서브쿼리를 사용할 때는 그 쿼리가 어떤 값을 반환하는지 주의할 필요가 있습니다. SELECT 쿼리를 실행 시 여러가지 패턴들이 나올수 있지만 일반적인 패턴에 대해 아래 표에 설명하겠습니다.


#

쿼리

설명

1

SELECT MIN(컬럼) FROM 테이블명

하나의 값을 반환

2

SELECT 컬럼 FROM 테이블명

하나의 컬럼에 복수의 레코드

3

SELECT MIN(컬럼1), MAX(컬럼2) FROM 테이블명

하나의 레코드 복수의 컬럼

4

SELECT 컬럼1, 컬럼2 FROM 테이블명

복수의 레코드 복수의 컬럼

[표 11. SELECT 쿼리 실행 시 반환되는 일반적인 패턴]


[표 11]에서 보면 다른 패턴과 다르게 1번 패턴은 하나의 값만을 반환합니다. 이렇게 SELECT 쿼리가 하나의 값만 반환하는 것을 단일값 또는 스칼라 값 이라고 합니다.

  1. WHERE 구에서 사용

WHERE 구에서 서브쿼리는 조건식에서 변수와 같이 사용이 가능합니다.

예를 들어 하나의 테이블에서 특정 컬럼의 최소 값을 찾아서 해당 레코드를 삭제해야 하는 경우를 생각해 보겠습니다. 이때 테이블에 데이터가 적고 한눈에 확인이 가능한 정도라면 눈으로 찾을 수 있겠지만 보통은 그렇게 찾을 수 없습니다. 이때 서브쿼리를 활용한다면 보다 쉽게 쿼리 작성이 됩니다.

먼저 서브쿼리는 해당 컬럼의 최소값을 찾을 것입니다.


1

SELECT MIN(컬럼) FROM 테이블;

[표 12. 최소값을 찾는 서브쿼리]


[표 12]와 같이 서브쿼리 작성이 되었다면 실제 레코드 삭제 부분에 적용해 보겠습니다.


1

DELETE FROM 테이블 WHERE 컬럼 = (SELECT MIN(컬럼) FROM 테이블);

[표 13. 최소값을 가진 레코드를 삭제하는 쿼리]


생각보다 간단하죠? 서브쿼리의 스칼라값을 조건식의 변수로 지정하여 사용하는 방법입니다. 하지만 데이터베이스별로 해당 쿼리가 실행이 되지 않을 수 있습니다.

동일한 테이블 내에서 추가나 갱신할 경우 서브쿼리가 제한될 수 있으니 사용하시는 데이터베이스 메뉴얼을 확인하길 바랍니다.

  1. SELECT 구에서 사용

SELECT 구에서 서브쿼리를 지정할 때는 스칼라 서브쿼리가 필요합니다.


1

SELECT

(SELECT COUNT(*) FROM 테이블명) AS sq;

[표 14. SELECT 구에서 서브쿼리 사용 방법]


[표 14]에서는 주의할 점이 있습니다. 서브쿼리가 아닌 상부의 SELECT 구에 FROM 구가 없다는 것입니다. 이것이 MySQL에서는 실행이 되지만 ORACLE과 같이 데이터 베이스에 따라 실행이 되지 않을 수 있습니다. 그럴때는 FROM 구를 정의해 줘야 합니다. 예를 들어 Oracle을 보면 FROM DUAL로 지정하면 실행할 수 있습니다. 다른 데이터베이스를 사용하신다면 메뉴얼을 확인하길 바랍니다.

  1. SET 구에서 사용

UPDATE의 SET구에서도 서브쿼리를 사용할 수 있습니다. SET 구에서도 서브쿼리를 사용할 때 스칼라 서브쿼리를 지정할 필요가 있습니다.


1

UPDATE 테이블 SET 컬럼 = (SELECT MAX(컬럼) FROM 테이블);

[표 15. SET구에서 서브쿼리 사용 방법]

  1. FROM 구에서 사용

지금까지는 FROM 구에서 테이블명을 지정하였습니다. 하지만 FROM 구에도 서브쿼리를 지정할 수 있습니다. 위에서는 서브쿼리를 사용할 때 스칼라 서브쿼리를 사용하라고 했었지만 FROM 구에서 사용되는 서브쿼리는 스칼라 값을 반환하지 않아도 됩니다.


1

SELECT * FROM (SELECT * FROM 테이블2);

[표 16. FROM 구에서 서브쿼리 사용 방법]


구조가 조금 특이하게 SELECT 쿼리 안에 SELECT 쿼리가 들어 있는 것처럼 보입니다. 이런것은 ‘네스티드 구조' 또는 ‘중첩구조', ‘내표 구조'라고 합니다.

[표 16]은 2단계 중첩 구조입니다. 중첩 구조는 몇단계를 구성해도 상관은 없습니다. 하지만 3단계 이상은 추천하지 않습니다.

  1. INSERT에서 사용

INSERT 쿼리에서도 VALUES 구의 일부로 서브쿼리를 사용할 수 있고, VALUE 구 대신 SELECT 쿼리를 사용하는 두가지 방법이 있습니다.


첫째, VALUES 구의 일부로 사용될 때

이때는 서브쿼리는 스칼라 서브쿼리를 사용해야 하고 자료형도 일치해야 합니다.


1

INSERT INTO 테이블 VALUES (

  (SELECT COUNT(*) FROM 테이블2), ...

);

[표 17. VALUES 구의 일부로 서브쿼리 사용 방법]


둘째, VALUES 구 대신 서브쿼리가 사용될 때

흔히 ‘INSERT SELECT’라 불리는 쿼리입니다. INSERT SELECT 쿼리는 SELECT 쿼리의 결과를 INSERT INTO로 지정된 테이블에 전부 추가합니다. 여기서 주의할 것은 SELECT 쿼리에서 반환하는 컬럼의 수와 자료형이 INSERT할 테이블과 일치해야 합니다. 그래서 INSERT SELECT는 테이터의 복사나 이동을 할 때 자주 사용됩니다.


1

INSERT INTO 테이블 SELECT * FROM 테이블2;

[표 18. VALUES 구 대신 SELECT 쿼리를 사용하는 방법]


반응형
반응형
  1. 집계 함수

이번에는 대표적인 집계 함수 COUNT, SUM, AVG, MIN, MAX와 GROUP BY를 사용하여 그룹화하는 방법을 알아보겠습니다.

SQL은 집합을 다루는 집계함수를 제공합니다. 일반적으로 함수는 파라미터로 하나의 값을 지정합니다. 하지만 집계함수의 경우는 파라미터로 집합을 지정합니다.

여기서 얘기하는 집계함수의 파라미터로 집합을 지정한다는 말이 쉽게 이해하기 어려울 수 있습니다. 이것에 대해서는 COUNT에서 한번 설명해 보겠습니다.

    1. COUNT

COUNT 함수는 파라미터로 주어진 집합의 개수를 반환합니다.


1

SELECT COUNT(컬럼명) FROM 테이블명 WHERE 조건식;

[표 1. COUNT 함수의 사용 방법]


간단합니다. 뭘 어떻게 더 설명하기 어려울 정도로 간단합니다.


추가로 설명을 하면 COUNT 집계를 사용할때 컬럼의 값 중 NULL이 있을 경우 NULL은 포함하지 않습니다. 또한 중복 데이터의 경우는 별도로 중복제거를 하지 않는다면 포함하여 집계합니다.

그러면 중복을 제외하고 집계해야하는 상황에서는 어떻게 해야할까요?

DISTINCT를 지정한 컬럼은 중복값을 제외하고 결과를 반환하는 함수입니다.

그래서 DISTINCT를 사용한 결과를 집계 함수에 적용하면 중복값을 제거한 집계 결과를 확인할 수 있습니다.


1

SELECT COUNT(DISTINCT 컬럼명) FROM 테이블명 WHERE 조건식;

[표 2. DISTINCT 를 이용한 COUNT 함수 사용 방법]

    1. SUM

집합 연산 중에서 합계를 구하기 위해 자주 사용하는 것이 SUM 함수입니다.

SUM 함수를 사용하면 지정한 컬럼의 합계를 구할 수 있습니다. 집계 가능한 범위는 수치형 데이터만 가능합니다. 문자열이나 날짜형의 데이터를 지정할 수 없습니다.

SUM도 COUNT와 마찬가지로 NULL 값을 제거한 뒤에 합계를 반환합니다.


1

SELECT SUM(컬럼명) FROM 테이블명 WHERE 조건식;

[표 3. SUM 함수 사용 방법]

    1. AVG

평균값을 구하기 위해서는 SUM / COUNT 와 같이 지정하면 구할 수 있지만 굳이 저렇게 사용하지 않아도 간단히 평균값을 구할 수 있습니다. 바로 AVG 함수를 이용하면 됩니다. AVG 함수는 지정한 컬럼의 평균값을 구하는 함수로서 SUM과 마찬가지로 수치형만 가능합니다.

AVG 함수도 NULL값은 제거한 뒤에 계산을 합니다. 하지만 NULL을 0으로 간주해서 평균을 내고 싶다면 CASE를 이용해서 NULL을 0으로 변환한뒤 AVG를 사용하면 됩니다.


1

SELECT AVG(컬럼명) FROM 테이블명 WHERE 조건식;

[표 4. AVG 함수 사용 방법]

    1. MIN / MAX

MIN, MAX 함수는 컬럼에서 최소값과 최대값을 구할 수 있습니다.

위의 다른 함수와 달리 문자열과 날짜형에도 사용할 수 있고 NULL 값은 무시합니다.


1

SELECT MIN(컬럼명), MAX(컬럼명) FROM 테이블명;

[표 5. MIN, MAX 함수 사용 방법]

    1. GROUP BY

GROUP BY 에 컬럼을 지정하여 그룹화하면 지정된 컬럼의 값이 같은 레코드들이 하나의 그룹으로 묶입니다.

각 그룹에 묶인 값들은 동일합니다. 그래서 GROUP BY를 사용하면 DISTINCT와 같이 중복을 제거하는 효과가 있습니다.

그렇다면 DISTINCT와 GROUP BY는 무슨 차이가 있을까요?

두가지 함수 모두 중복값을 제거 한다는것은 동일하지만 GROUP BY는 집계 함수와 쓰이지 않으면 별 의미가 없습니다. GROUP BY로 그룹화하고 각각의 그룹을 집계 함수에서 파라미터로 사용해야 GROUP BY가 의미가 있습니다.


1

SELECT SUM(컬럼명) FROM 테이블명 GROUP BY 컬럼명;

[표 6. GROUP BY 사용 방법]

    1. HAVING

그러면 그룹화를 시키고 집계 함수를 사용할 때 WHERE 구의 조건식에는 집계 함수를 사용할 수는 없을까요? 네 없습니다. 그룹화가 필요한 집계 함수는 WHERE 구에서 지정할 수 없습니다.

이게 무슨 말일까요 아래 표를 보고 설명 드리겠습니다.


1

SELECT SUM(컬럼명) FROM 테이블명 WHERE COUNT(컬럼명) = 1 GROUP BY 컬럼명;

[표 7. WHERE 구에서 집계 함수 사용]


[표 7]에서 사용한 문법 사용대로 한다면 에러가 발생합니다.

그 이유는 GROUP BY와 WHERE 구의 처리 순서 때문입니다. WHERE 구의 처리는 GROUP BY 보다 빠릅니다. 그래서 그룹화가 되기전에 조건절에서 컬럼을 집계하려고 하면 에러가 발생하는 것입니다.

쿼리의 내부처리 순서를 다시 한번 살펴 보겠습니다.


순위

1

WHERE

2

GROUP BY

3

SELECT

4

ORDER BY

[표 8. 쿼리의 내부 처리 순서]


지금까지 HAVING을 설명하기전 다른것은 왜 안되는지에 대해 먼저 살펴 보았습니다.

우리가 원하는대로 집계한 결과에서 조건에 맞는 값을 가져오기 위해서는 HAVING을 사용하면 됩니다.


HAVING은 GROUP BY 구 뒤에 기술하고 WHERE와 동일하게 조건식 지정이 가능합니다. 즉, 그룹화된 컬럼을 이용하여 조건식에서 집계 함수를 사용할 수 있다는 것입니다.

[표 8]에서 설명한 쿼리의 내부처리 순서에 HAVING이 들어간다면 2번째인 GROUP BY 다음에 들어가게 됩니다.


순위

1

WHERE

2

GROUP BY

3

HAVING

4

SELECT

5

ORDER BY

[표 9. HAVING을 추가한 쿼리의 내부 처리 순서]


1

SELECT SUM(컬럼명) FROM 테이블명 GROUP BY 컬럼명 HAVING COUNT(컬럼명) = 식;

[표 10. HAVING을 이용한 조건식 사용법]


반응형
반응형
  1. INSERT

이전 글들은 SELECT를 활용해서 데이터를 검색하는 것이었다면 지금은 데이터를 입력할 때의 방법을 설명하겠습니다.


우리가 게시판을 하나 만들었다고 한다면 최초 서비스가 올라갔을 때는 게시글이 하나도 없을 것입니다. 그러면 우리는 ‘글쓰기' 또는 ‘만들기’와 같은 버튼을 클릭했을 때 데이터 추가 기능을 사용할 것입니다. 여기서 사용하는 것이 INSERT라고 생각하면 됩니다.

    1. INSERT로 레코드 추가하기

RDBMS에서는 INSERT 명령으로 레코드 단위로 데이터를 추가합니다.


1

INSERT INTO 테이블명 VALUES (값1, 값2, 값3 ...);

[표 1. INSERT를 사용하는 방법]


해당 쿼리의 형식으로 실행 시 지정한 테이블에 레코드가 추가됩니다.


INSERT 쿼리는 실행을 하면 처리 상태만 표시되고 SELECT와 같이 실행했을 때 결과를 보여주지 않습니다. 제대로 들어갔는지 확인하기 위해서는 SELECT 쿼리를 실행하여 확인하면됩니다.


스크린샷 2017-02-21 오후 3.06.33.png

[그림 1. INSERT 쿼리 실행과 검색]

    1. 값을 저장할 컬럼 지정하기

INSERT 쿼리 실행 시 테이블명만 지정하고 컬럼명을 지정하지 않을 경우는 모든 컬럼의 값을 VALUES 부분에 모든 컬럼에 대한 값을 지정해야 합니다.

하지만 테이블을 지정하고 괄호로 값을 넣을 컬럼명을 지정할 경우 해당 컬럼에만 값이 들어갑니다.


1

INSERT INTO 테이블명 (컬럼1, 커럼2 …) VALUES (값1, 값2, 값3 ...);

[표 2. 컬럼을 지정하여 값 지정]


스크린샷 2017-02-21 오후 3.14.44.png

[그림 2. 컬럼을 지정하여 실행한 결과]

    1. NOT NULL

레코드를 추가할 때 NULL을 지정하고 싶을 경우에는 VALUES에서 NULL로 값을 지정할 수 있습니다.


1

INSERT INTO 테이블명 VALUES (NULL, NULL, NULL ...);

[표 3. NULL값을 지정]


스크린샷 2017-02-21 오후 3.15.27.png

[그림 3. NULL 값을 지정하여 실행한 결과]


지금 샘플 테이블에는 모든 컬럼이 NULL을 허용하고 있습니다. 그런데 만약 컬럼 중 NOT NULL 제약이 걸려있는 것이 있다고 하면 샘플로 실행한 쿼리는 에러가 발생합니다. 그 이유는 NOT NULL 제약이 걸려 있는 컬럼은 NULL 값을 허용안되기 때문입니다.

    1. DEFAULT

DEFAULT는 명시적으로 값을 지정하지 않았을 경우 사용하는 초기값을 말합니다. 이것은 테이블을 정의할 때 지정할 수 있습니다.


DEFAULT는 두가지 방법으로 사용할 수 있습니다.

DEFAULT를 명시하는 방법과 암묵적으로 디폴트를 사용하는 방법이 있습니다.

보통 INSERT 사용 시 디폴트가 지정되어 있는 컬럼을 제외하고 쿼리를 실행 합니다. 그렇게 실행을 하더라도 컬럼의 값이 디폴트로 저장이 되기 때문입니다.

  1. DELETE

서비스를 하다보면 데이터를 삭제해야 하는 경우가 있습니다.

예를 들어 게시판의 글 중에 글을 하나 삭제한다고 했을 때 ‘삭제' 또는 ‘지우기'같은 버튼을 클릭 했을 때 데이터 삭제 기능을 사용할 것입니다.

    1. DELETE로 레코드 삭제하기

RDBMS에서 데이터를 삭제할 경우에는 DELETE 쿼리를 실행합니다.


1

DELETE FROM 테이블명 WHERE 조건식;

[표 4. DELECT를 사용하는 방법]


[표 4]에서 WHERE 조건식이 없다면 테이블의 모든 레코드를 삭제하게 됩니다. 그래서 조건에 부합하는 레코드만 삭제되도록 조건식을 넣어줘야 합니다.


아마 컬럼의 데이터만 삭제할 수 있지 않을까? 라고 생각하시는 분들이 있습니다. 결론은 안된다. 입니다. 컬럼 단위로 삭제가 아닌 레코드 단위이고 조건에 일치하는 모든행을 삭제하므로 사용시 주의해야 합니다.


스크린샷 2017-02-21 오후 3.40.30.png

[그림 4. DELETE 쿼리를 실행한 결과]

  1. UPDATE

데이터 갱신 작업은 시스템에서 자주 발생합니다.

예를 들어 게시판에서 게시글을 수정할 때 ‘수정' 또는 ‘갱신'과 같은 버튼을 클릭 시 내부적으로 데이터 갱신 기능을 사용할 것입니다.

    1. UPDATE로 데이터 갱신하기

RDBMS에서는 UPDATE 쿼리로 데이터를 갱신할 수 있습니다. 이것은 테이블의 셀 값을 갱신하는 명령입니다.


1

UPDATE 테이블명 SET 컬럼명 = 값 WHERE 조건식;

[표 5. UPDATE의 사용 방법]


DELETE와 달리 셀 단위로 데이터를 갱신할 수 있습니다. WHERE 조건식을 일치하는 모든 레코드를 갱신할 수 있습니다. 만약 WHERE 조건식을 제외한다면 테이블의 모든 레코드가 갱신됩니다.


스크린샷 2017-02-21 오후 3.49.38.png

[그림 5. UPDATE 쿼리를 실행한 결과]

    1. 복수의 컬럼 갱신

위에서는 컬럼 하나에 대한것만 갱신을 하였습니다. 이번에는 복수의 컬럼을 갱신할 때 UPDATE를 어떻게 사용해야하는지 보겠습니다.


1

UPDATE 테이블명 SET 컬럼명1 = 값1, 컬럼명 2 = 값2, …  WHERE 조건식;

[표 6. 복수의 컬럼을 지정한 UPDATE 사용 방법]


스크린샷 2017-02-21 오후 4.33.05.png

[그림 6. 복수의 컬럼을 지정한 UPDATE 쿼리 실행 결과]


만약 NULL로 데이터를 초기화하려고 한다면 컬럼명 = NULL 로 지정하면 됩니다. 이런것을 NULL 초기화라고 합니다. 대신 갱신하려는 컬럼이 NOT NULL 제약 조건이 걸려있는것은 아닌지 확인하고 실행하면 됩니다.

  1. 물리 삭제, 논리 삭제

실제 서비스를 진행하면서 데이터를 삭제할 때 데이터를 삭제해 버리는 경우와 별도 삭제 플래그를 넣어서 실제 레코드는 삭제되지 않지만 플래그 값을 기준으로 삭제를 판단하는 경우가 있습니다. 여기서 말하는 삭제하는 것을 물리삭제, 삭제 플래그를 지정하는 것을 논리 삭제라고합니다.

왜 이렇게 사용한다라고 말을 하기보다는 데이터 특성이나 서비스 운영 정책에 따라 달라지기 때문에 뭐라 단정지어서 말하기 어렵습니다.

어느 테이블의 경우는 데이터를 삭제를 해야하고 어느 테이블은 삭제 플래그를 넣고 데이터는 유지하는 것처럼 섞여서 사용되기 때문에 내부 서비스 정책 및 용도에 맞게 선택하여 사용하면 될 것 같습니다.



반응형
반응형
  1. 수치 연산

SQL은 기본적으로 계산 기능을 포함하고 있습니다. 이번에는 이런 계산하는 기능을 사용하는 방법 중 수치 데이터의 연산에 대해 이야기 하겠습니다. 수치 연산을 하는 산술 연산의 경우는 다른 프로그래밍에서도 사용하는 기본 개념이니 기존에 프로그래밍을 하셨던 분들은 익숙하실 수 있고, 처음 접하시는 분은 이번에 잘 알아두길 바랍니다.

    1. 사칙 연산

사칙 연산은 우리가 알고 있는 덧셈, 뺄셈, 곱셈, 나눗셈에 한가지 더 있다면 나눗셈의 나머지를 구하는 것 입니다. 연산자는 기호로 표기하고 아래 표로 정리해 보겠습니다.


연산자

연산

+

덧셈

1+2 → 3

-

뺄셈

1-2 → -1

*

곱셈

1*2 → 2

/

나눗셈

½ → 0.5

%

나머지

1%2 → 1

[표 9. 산술 연산자]


[표 9]의 연산자들은 여러 데이터베이스에서 동일하게 사용합니다. 하지만 나머지를 구하는 %는 데이터베이스 제품마다 차이가 있을 수 있습니다. 보통은 % 또는 MOD 함수를 사용하는 경우도 있습니다.


산술 연산자는 우선 순위가 있습니다. 하지만 이미 산수를 다 알고 계실 것이라 생각합니다. 간단하게 표로 정리하고 넘어 가겠습니다.



우선순위

연산자

1

* / %

2

+ -

[표 10. 산술 연산자 우선순위]


지금까지 SQL에서 사용하는 산술 연산자에 대해 간단히 알아 보았습니다. 그러면 쿼리에서 산술 연산자는 어디서 사용하는지 알아 보겠습니다.

    1. SELECT 구에서 연산

SELECT 구에는 컬럼명을 지정할 수도 있지만 여러가지 식을 기술할 수 있습니다. 여기서 사용하는 식은 컬럼명, 연산자, 상수로 구성됩니다.



1

SELECT *, 컬럼명1 * 상수 FROM 테이블명;

[표 11. SELECT 구에서 식의 사용]


스크린샷 2017-02-20 오후 5.27.00.png

[그림 8. SELECT 구에서 식을 사용한 결과]


위 예제의 결과를 보면 사용한 식의 내용이 결과의 컬럼명이 사용한 식의 내용으로 들어가 있는것을 볼 수 있습니다. 식이 그대로 보이면 이름이 길고 사용하기도 불편하고 알아보기도 어렵습니다. 이것을 바꾸는 방법을 알아 보겠습니다.

    1. 컬럼 별명 설정

SELECT에서 사용한 식의 결과에서 결과 컬럼명을 내가 원하는 이름으로 재지정할 수 있습니다. 바로 예약어 AS를 사용하는 것입니다.


1

SELECT *, 컬럼명1 * 상수 AS 별명 FROM 테이블명;

[표 12. AS를 사용한 컬럼 별명 지정]


스크린샷 2017-02-20 오후 5.27.52.png

[그림 9. AS를 사용하여 별명을 지정한 결과]


SELECT 구에서는 콤마(,)로 구분한 복수의 식을 지정할 수 있고 각각의 식에 별명을 붙일 수 있습니다. 중복의 이름을 사용할 수는 있지만 결과의 처리가 불분명해집니다. 중복되지 않게 사용해야 합니다.


예약어 AS는 생략할 수 있습니다. 그리고 별명을 지정할 때 한글로 지정하는 경우에는 더블쿼트로 감싸야 합니다. 감싸지 않아도 동작을 하는 경우가 있을 수 있으나 오작동하는 경우들이 많이 발생합니다. 그렇기 때문에 감싸주는것이 좋습니다.


1

SELECT *, 컬럼명1 * 상수 “별명” FROM 테이블명;

[표 13. AS의 생략과 한글의 더블쿼드 사용]


스크린샷 2017-02-20 오후 5.29.45.png

[그림 10. AS를 제외하고 한글 별명을 사용한 결과]


또한 별명을 붙일 때는 숫자로 시작할 수 없습니다. 이름이 숫자로 시작한다면 그것이 수치형 상수를 의미하는 것인지 데이터베이스 객체명을 의미하는지 구별할 수 없습니다. 그래서 데이터베이스명은 ‘숫자로 시작하면 안된다'라는 제약이 생겼습니다. 더블쿼트로 묶는다면 사용할 수는 있지만 추천하지는 않습니다.

    1. WHERE 구에서 연산

SELECT 구에서 연산을 할 수 있지만 WHERE에서도 연산이 가능합니다.


1

SELECT *, 컬럼명 * 상수 AS “별명" FROM 테이블명 WHERE 컬럼명 * 상수 >= 비교값;

[표 14. WHERE 구에서 식의 사용]


[표 14]와 같이 WHERE 구에서 식을 사용할 수 있습니다. 여기서 WHERE 구의 컬럼명 * 상수 부분을 SELECT 구에서 정의한 별명인 “별명"으로 사용하면 안되는지 궁굼할 수 있습니다. 결론은 안된다 입니다. 그 이유는 쿼리의 내부 처리 순서가 다르기 때문입니다.

데이터베이스 서버 내부에서는 WHERE 구를 먼저 처리하고 SELECT 구를 처리합니다. 그래서 SELECT 구에서 지정한 별명은 WHERE 구 안에서 사용할 수 없습니다.

    1. NULL 값의 연산

NULL을 이용해서 연산을 어떻게 결과가 나올지 한번 보겠습니다.

‘NULL + 1’을 했을 때 결과가 어떻게 나올까요?

많은 분들이 1이라고 대답을 합니다. 왜 그럴까요? 아마도 다른 언어의 프로그래밍에서는  NULL을 0으로 간주해서 계산을 했기 때문입니다.


SQL에서 NULL은 유효한 값이 없는 상태입니다. NULL은 0이 아닙니다. 그래서 NULL에 어떤 연산을 하더라도 결과는 NULL입니다.

    1. ORDER BY에서 연산

ORDER BY에서 연산은 다른것은 아니고 SELECT 구에서 지정한 식의 결과를 ORDER BY에서 정렬이 가능합니다.


1

SELECT *, 컬럼명 * 상수 AS “별명" FROM 테이블명 ORDER BY “별명”;

[표 15. 식의 결과로 정렬하기]


스크린샷 2017-02-20 오후 5.34.01.png

[그림 11. order by에서 별명을 지정한 결과]


[표 15]를 보면 조금 이상한 부분 없으신가요?

WHERE 구를 설명할 때는 SELECT에서 지정한 별명을 WHERE 구에서 사용할 수 없다고 설명했습니다. 근데 ORDER BY에서는 별명을 사용하고 있습니다. 무엇이 다른것일까요?

네. 쿼리의 처리 순서가 여기서도 나옵니다. ORDER BY는 서버 내부에서 가장 나중에 처리됩니다. 그래서 SELECT 구에서 지정한 별명을 ORDER BY에서도 사용할 수 있는 것입니다.

    1. 함수

지금까지는 연산자를 사용해 보았습니다. 그렇지만 연산자만 사용하는 것은 아닙니다. 연산자외에도 함수를 사용할 수도 있습니다.


1

SELECT 함수명(파라미터 1, 파라미터 2) AS “별명" FROM 테이블명;

[표 16. 함수의 사용법]


데이터베이스 종류마다 제공하는 함수는 차이가 날 수 있습니다. 하지만 구조는 다 비슷합니다. 그러면 한가지 함수를 다음에서 설명해보겠습니다.

    1. ROUND 함수

데이터가 소수점을 가지고 있을 경우 거래되는 단위를 고려해 반올림을 하는데 이때 사용하는 것이 ROUND 함수입니다.


1

SELECT ROUND(컬럼명 또는 식) FROM 테이블;

[표 17. ROUND 함수의 사용]


ROUND 함수는 기본적으로 소수점 첫째 자리를 기준으로 반올림한 값을 반환합니다. 첫째 자리를 기준으로 반올림할 수도 있지만 두번째 파라미터를 지정하여 반올림할 자릿수를 지정할 수 있습니다. 두번째 파라미터를 생략하는 경우는 0으로 간주해서 처째 자리를 반올림합니다. 만약 두번째 파라미터를 음수로 지정할 경우 정수부의 반올림할 자릿수도 지정할 수 있습니다.


반올림이 아니라 버림을 할때는 TRUNCATE을 사용할 수 있습니다.


이것 외에도 여러가지 함수들이 많이 있습니다. 그런것들은 사용하시는 데이터베이스의 메뉴얼을 참고해주세요.

  1. 문자열 연산

지금까지 수치형 데이터의 연산을 알아봤다면 지금은 문자열형 데이터의 연산에 대해 알아보겠습니다. 문자열형 데이터 연산은 연산자가 그렇게 많지가 않습니다. 그래서 자주 사용하는 몇가지 함수에 대해 표로 정리하겠습니다.


연산자/함수

설명

+/||/CONCAT

문자열을 결합한다.

SQL Server는 +

Oracl, DB2, PostgreSQL 은 ||

MySQL 은 CONCAT 함수를 사용한다.

SUBSTRING

SUBSTR

문자열의 일부분을 계산하여 반환해주는 함수

TRIM

문자열의 앞뒤로 공백이 있을 경우 제거해주는 함수.

문자열 중간의 스페이스는 제거되지 않은다.

CHARACTER_LENGTH

문자열의 길이를 계산하는 함수

OCTET_LENGTH

문자열의 길이를 바이트 단위로 계산하는 함수

문자 인코딩 설정에 따라 길이가 다를 수 있다.

[표 18. 문자열 연산]

  1. 날짜 연산

날짜, 시간 데이터를 저장하는 방법은 데이터베이스마다 크게 다릅니다. 사용하는 데이터베이스의 날짜 저장 방식을 먼저 살펴 보시길 바랍니다.

실제 시스템에서 날짜 연산은 빈번하게 일어납니다. 날짜 정보를 유용하게 사용하는 법을 알아보겠습니다.

    1. 덧셈과 뺄셈

날짜형 데이터는 기간 형식의 수치 데이터와 덧셈, 뺄셈을 할 수 있습니다.날짜 데이터에서 기간 형식의 수치 데이터를 더하거나 빼면 됩니다.

예를 들기에는 기간형 상수의 기술 방법이 데이터베이스마다 다르고 세세한 부분까지 표준화가 이루어지지 않아서 어렵고 자세한 내용은 데이터베이스의 매뉴얼을 참고하길 바랍니다.

  1. CASE 문으로 데이터 변환하기

CASE 문을 이용할 경우 데이터를 변환할 수 있습니다.

이미 준비된 함수를 사용해서 데이터를 특정한 형태로 변환하는 경우도 있지만 임의의 조건에 따라서 데이터를 변환하고 싶을 때 CASE 문을 사용합니다.

    1. CASE 문이란?

먼저 CASE 문의 사용법을 보겠습니다.


1

CASE WHEN 조건식 1 THEN 식 1

[ WHEN 조건식 2 THEN 식 2 ... ]

[ ELSE 식3 ]

END

[표 19. CASE문의 사용]


WHEN 절에는 참과 거짓을 반환하는 조건식을 기술합니다. 조건을 만족하는 경우 THEN 절에 기술에 식을 처리합니다. 다수의 WHEN … THEN ...을 사용했을때 순차적으로 조건식을 실행하게 되고 어떤 조건식도 만족하지 않을때는 ELSE에 기술한 식을 처리합니다.


만약 NULL 값을 변환할 때 CASE를 사용해서 0으로 변환할 수 있습니다. 하지만 이때 CASE를 사용하는 것보단 COALESCE 함수를 사용하는 것이 더 쉽습니다.


1

SELECT COALESCE(컬럼명, 0) FROM 테이블;

[표 20. COALESCE 함수의 사용]


컬럼의 값이 NULL일 경우 0을 반환하고 아닐경우는 컬럼의 값을 그대로 반환합니다.

    1. CASE의 다른 사용법

위에서는 CASE에서 식을 실행하는 것이었다면 여기서 설명할 내용은 숫자로 이루어진 코드를 알아보기 쉽게 문자열로 변환하는 것입니다.


예를 들어 1은 남자 2는 여자라는 코드 체계가 있다면 모르는 사람이 봤을 때 1, 2 코드를 보여주면 이해가 안되지만 남자, 여자라고 표시하면 이해하기 쉬울것입니다.


코드를 문자와 하는것은 ‘디코드', 문자를 수치화 하는것을 ‘인코드'라고 합니다.


1

WHEN a=1 THEN ‘남자'

WHEN a=2 THEN ‘여자'

[표 21. CASE 문을 사용한 디코드]

    1. 주의 사항

      • ELSE를 생략하게 되면 ELSE NULL이 되는것에 주의해야 합니다. 조건에 만족하는 WHEN 절이 하나도 없을경우 ELSE가 사용되며 NULL을 반환합니다. 그렇기 때문에 NULL이 반환되지 않도록 ELSE로 반환될 값을 지정하는것이 좋습니다.

      • WHEN에서 NULL인지 확인하기 위해서는 = 연산자를 사용하는 것이 아닌 IS NULL을 사용합니다. 단순한 비교 연산자 만으로는 NULL 값을 비교할 수 없습니다.


반응형
반응형
  1. 검색 조건 조합

SELECT 쿼리를 사용하여 검색 시 실제로는 하나의 조건만 사용하는 경우보다 2개 이상의 조건식을 조합해 검색하는 경우가 많이 있습니다. 이렇게 조건식을 조합할 때 사용하는 AND, OR, NOT 3가지에 대해서 알아 보겠습니다.

    1. AND 조건

복수 조건을 조합할 때 AND를 많이 사용합니다.

AND는 논리 연산자의 하나로 좌우에 항목이 필요한 이항 연산자입니다.

좌우의 조건식이 모두 참일 경우 AND는 참을 반환합니다. 그래서 좌우 조건식, 즉, 모든 조건을 만족할 경우 조건식은 참이된다라고 할 때 AND를 사용합니다.


“SELECT * FROM 테이블명 WHERE 조건식1 AND 조건식2;”


AND는 위와 같은 문법으로 사용합니다.


AND 연산은 조건을 만족하는 레코드을 집합으로 표현했을 때 이들 집합이  겹쳐지는 부분, 즉 교집합으로 계산 할 수 있습니다. 그렇기 때문에 AND로 조건식을 연결하면 모든 조건을 만족하는 레코드를 검색할 수 있습니다.

    1. OR 조건

OR는 어느 쪽이든 하나만 참이 되면 조건식은 참이된다라고 할 경우에 사용합니다.

OR도 AND와 마찬가지로 좌우 항목이 모두 필요한 이항 연산자입니다. AND와 달리 어느 쪽이든 조건을 만족하면 결과는 참이 됩니다. 대신 모든 조건이 거짓일 경우 결과는 거짓이 됩니다.


“SELECT * FROM 테이블명 WHERE 조건식1 OR 조건식2;”


OR는 위와 같은 문법으로 사용합니다.


조건을 만족하는 레코드를 집합으로 표현했을 때 AND 연산과는 다르게 합집합으로 계산할 수 있습니다. 그래서 어느 쪽이든 조건을 만족하는 레코드를 모두 검색할 수 있습니다.

    1. AND와 OR 사용 시 주의점

조건식을 조합을 하다보면 AND와 OR를 혼합하여 사용하는 경우가 있습니다. 그렇게 사용했을 때 자신이 생각했던 결과와 다른 결과를 보고 당황한 경우들이 있을겁니다.

그 이유는 AND와 OR의 경우 연산 우선 순위가 있기 때문입니다.

결론을 먼저 얘기하면 AND가 OR보다 연산 우선 순위가 높습니다.

만약 이런 조건이 있다고 생각해 보겠습니다.

“WHERE 조건1 OR 조건2 AND 조건3 OR 조건4”

위 조건식을 우선순위를 쉽게 보기 위해서 아래와 같이 생각할 수 있습니다.


“WHERE 조건1 OR (조건2 AND 조건3) OR 조건4”


즉, 3개의 조건식이 OR로 연결된 것과 같다고 생각하면 됩니다.

만약 두개의  OR연산은 AND로 연산하고 싶다면 아래와 같이 괄호로 우선 순위를 변경하면 됩니다.

“WHERE (조건1 OR 조건2) AND (조건3 OR 조건4)”

    1. NOT 조건

NOT 연산자는 오른쪽에만 항목을 지정하는 단항 연산자입니다.

오른쪽에 지정한 조건식의 반대값을 반환합니다. 만약 참을 반환하는 조건식에 NOT을 사용하면 거짓을 반환하게 됩니다.


레코드를 집합으로 표현 했을 때 합집합 영역을 제외한 그 나머지 부분을 나타낼 수 있습니다.

  1. 패턴매칭

= 연산자를 사용할 경우 셀의 데이터 값이 완전하게 동일한 것들을 검색합니다. 하지만 특정 문자나 문자열이 포함되어 있는지 검색할 경우가 있습니다. 이런 경우 사용하는 것이 패턴 매칭 또는 부분 검색입니다. LIKE 를 사용하면 문자열의 부분 검색이 가능합니다.

간단한 패턴 매칭이라면 LIKE로 충분하지만 조금 더 복잡한 패턴을 매칭하는 경우에는 정규 표현식을 사용하는 것을 추천합니다.

    1. LIKE로 패턴 매칭

LIKE 연산자는 아래와 같이 사용이 가능합니다.


“컬럼명 LIKE ‘패턴' ”


왼쪽에는 매칭 대상을 지정하고 오른쪽에는 패턴을 문자열로 지정합니다. 대신 수치형 상수는 사용할 수 없고 메타문자 (%, _)는 사용할 수 있습니다.

와일드카드라고도 불리는 메타문자는 패턴 매칭 시 임의의 문자 또는 문자열에 매치하는 부분을 지정하기 위해 쓰이는 특수 문자입니다.

또한 와일드카드로 자주 쓰이는 애스터리스크(*)는 LIKE에서는 사용할 수 없습니다.



%

임의의 문자열을 의미

_

임의의 문자 하나를 의미

[표 7. LIKE 연산자의 패턴에서 특수 문자의 의미]


패턴 매칭을 사용하여 검색시 3가지 방법을 이용할 수 있습니다. 전방 일치, 중간 일치, 후방 일치 이렇게 3가지에 대해 간략하게 아래 표에서 설명하겠습니다.



전방 일치

문자열의 시작이 일치할 경우

WHERE 컬럼명 LIKE ‘패턴%’

중간 일치

문자열에 패턴이 포함된 경우

WHERE 컬럼명 LIKE ‘%패턴%’

후방 일치

문자열의 마지막이 일치

WHERE 컬럼명 LIKE ‘%패턴’

[표 8. 패턴 매칭 방법]

    1. LIKE로 % 검색

위에서 LIKE 사용시 패턴에는 %와 _를 사용할 수 있다고 했습니다. 그렇다면 메타 문자와 동일한 문자를 검색할 경우는 어떻게 해야할까요?

이러한 문제를 ‘이스케이프'라는 방법으로 처리할 수 있습니다. LIKE로 %를 검색하는 경우 ‘\%’와 같이 \를 % 앞에 붙이면 됩니다. 이것을 조건식으로 표현하면 다음과 같습니다.


“WHERE 컬럼명 LIKE ‘%\%%’ ”


%가 연속으로 나열되어 있어 보기 힘들수도 있지만 순서를 따라 확인하면 쉽게 이해할 수 있습니다. 예를 들지 않은 _도 %와 동일하게 검색하면 됩니다.

    1. 문자열 상수 ‘ 이스케이프

메타 문자를 검색할 때와 같이 문자열 상수를 검색할 때도 같은 문제가 발생합니다.

문자열 상수는 ‘문자열'과 같이 ‘로 둘러싸 표기합니다. 문자열 상수 안에 ‘를 포함하고 싶을 때는 어떻게 해야 할까요?

표준 SQL에서는 ‘를 2개를 연속해서 기술하는 것으로 이스케이프 처리를 할 수 있습니다. 예를 들어 보겠습니다.

‘It’s’라는 문자열을 문자열 상수로 표기하면 ‘It’’s’로 표기할 수 있습니다.

한가지 더 예를 들면 ‘하나만 문자열 데이터라면 어떻게 해야 할까요? ‘’’’로 쓰면 됩니다. ‘를 총 4번 쓰면됩니다.



반응형
반응형
  1. 검색 조건 지정

데이터베이스의 테이블에는 컬럼이 많이 있습니다. 

한번에 화면에 표시하여 확인할 수 있는 데이터의 양은 한정되어 있습니다. 

컬럼이나 레코드를 선택해서 데이터를 읽어오는 검색이 빈번하게 일어 납니다.

이번에는 컬럼이나 열을 선택해서 테이블의 데이터를 조회하는 방법에 대해 알아보겠습니다.


    1. SELECT 구에서 컬럼 지정

여기서는 데이터베이스의 테이블에서 자신이 원하는 컬럼들을 한정하여 검색하는 방법에 대해 알아보겠습니다.


결과로 표시하고 싶은 컬럼을 지정할 수 있습니다.


“SELECT 컬럼1, 컬럼2, 컬럼3, … FROM  테이블 명;


이전에 제가 올렸던 글에서 보면 샘플 데이터에서 컬럼의 정보들을 가져올때는 애스터리스크(*)를 사용하여 모든 컬럼을 표시하였습니다.

컬럼을 한정하기 위해서는 * 부분을 위의 쿼리처럼 “컬럼1, 컬럼2” 원하는 컬럼을 명시하고 구분은 콤마(,)를 이용하면 지정한 컬럼만 결과 값에 보여집니다.


스크린샷 2017-02-15 오전 11.09.34.png

[그림 3. 컬럼을 한정하여 데이터 조회]


만약 테이블에 존재하지 않는 컬럼이나 아무 컬럼도 지정하지 않을 경우 구문 에러가 발생합니다. 또한 컬럼을 지정할 때 지정 순서는 임의로 지정하거나 중복이 되어도 무관합니다. 지정한 컬럼의 순서에 따라 결과가 보여집니다.

    1. WHERE 구에서 레코드 지정

테이블의 컬럼은 많아야 몇십개지만 레코드는 컬럼에 비해 훨씬 많을 수 있습니다. 적으면 수백개 많으면 수천만건의 레코드가 있을 수 있습니다. 이렇게 많은 레코드에서 내가 필요한 데이터만 검색하기 위해서는 WHERE 구를 사용해야 합니다.


“SELECT 컬럼 FROM 테이블명 WHERE 조건식;


WHERE 구는 FROM 구의 뒤에 표기되며 WHERE 뒤에 검색 조건을 사용합니다.


위에서 보듯이 SQL에서는 구의 순서가 정해져 있어 바꿔서 적을 수가 없습니다. 만약에 위의 쿼리를 “select 컬럼 where 조건식 from 테이블명;” 순으로 적으면 에러가 발생합니다. 또한 WHERE 구처럼 생략 가능한 것도 있습니다.


WHERE 구에는 조건식이 들어갑니다.


스크린샷 2017-02-15 오전 11.29.55.png

[그림 4. 조건식을 적용하여 검색]


위 [그림 4]는 WHERE 구에 조건식을 적용하여 테이블의 데이터를 검색한 것입니다. 이렇게 조건식만 주어서 레코드를 검색할 수도 있지만 SELECT 구에 원하는 컬럼 지정을 동시에 사용할 수 있습니다.


스크린샷 2017-02-15 오전 11.29.07.png

[그림 5. 조건식과 컬럼 지정 동시 사용]


조건식을 간단히 살펴보면 id = 1 이것이 의미하는 것은 컬럼 명 id의 값이 1인 레코드를 검색하겠다는 것입니다. 조건식의 컬럼명은 상황에 맞는 것을 사용하면 되고 조건식이 참이 되는 결과 값만 반환을 하게 될것입니다.

조건식은 참 또는 거짓의 진리값을 반환하는 식으로 비교 연산자를 사용해 표현합니다.


만약 값이 서로 다른 경우를 검색하기 위해서는 어떻게 해야 할까요?

연산자로 ‘<>’을 사용하면 됩니다.


스크린샷 2017-02-15 오전 11.40.32.png

[그림 6. 연산자 <>을 사용하여 검색]


연산자 ‘<>’은 서로 다른 값인지를 비교하는 연산자입니다.

<> 연산자를 통해 ‘값이 서로 다른 경우’ 참이 되는 조건식으로 변경할 수 있습니다.


[그림 6]에서도 알 수 있듯이 복수의 레코드가 출력될 수도 있고 하나 또는 아무것도 반환되지 않을 수 있습니다.

    1. 문자열 상수

위에서 검색했던 조건식의 경우는 id가 수치형 데이터였습니다. 그러면 수치형 데이터가 아닌 문자열 데이터의 경우는 어떻게 검색을 해야할까요?


수치형 조건식의 경우는 “id = 1”과 같이 비교할 숫자를 그대로 조건식에 표기합니다. 하지만 문자열의 경우는 ‘김이빵'처럼 싱글 쿼트를 사용하여 둘러싸 표기해야 합니다. 날짜 또한 마찬가지입니다.


스크린샷 2017-02-15 오전 11.50.48.png

[그림 7. 싱글 쿼드없이 검색 시 에러]


스크린샷 2017-02-15 오전 11.53.17.png

[그림 8. 싱글 쿼트로 감싸서 검색한 결과]


한편 자료형에 맞게 표기한 상수값을 ‘리터럴(literal)’이라고 합니다.

문자열 리터럴은 싱글 쿼트로 둘러싸 표기합니다.

    1. NULL 검색

데이터 검색 시 NULL 값을 검색할 경우에는 조금 주의해야 합니다.

조건식을 birthday = NULL 과같은 식으로는 검색할 수 없습니다. 한마디로 = 연산자로는 검색이 안됩니다.


스크린샷 2017-02-15 오전 11.57.44.png

[그림 9. = 연산자를 사용하여 NULL 검색 결과]


NULL 값을 검색할 때는 = 연산자가 아닌 “IS NULL”을 사용하면 됩니다.


스크린샷 2017-02-15 오전 11.58.21.png

[그림 10. IS NULL을 사용하여 NULL 검색 결과]


반대로 NULL 값이 아닌 값을 검색하고 싶다면 “IS NOT NULL”을 사용하면 됩니다.


스크린샷 2017-02-15 오전 11.58.42.png

[그림 11. IS NOT NULL을 사용하여 검색한 결과]


    1. 비교 연산자

지금까지 =, <>, IS NULL, IS NOT NULL을 사용해서 검색하는 방법을 알아봤습니다. 

이것들과 같이 대표적으로 많이 사용하는 연산자를 알아보겠습니다.


연산자

설명

=

좌변 우변의 값이 같을 경우 참

<>

좌변과 우변이 같지 않을 경우 참

>

좌변의 값이 우변의 값보다 클 경우 참.

같거나 작을 경우 거짓

<

좌변의 값이 우변의 값보다 작을 경우 참

같거나 클 경우 거짓

>=

좌변의 값이 우변의 값보다 크거나 같을 경우 참

작을 경우 거짓

<=

좌변의 값이 우변의 값보다 작거나 같을 경우 참

클 경우 거짓

[표 6. 연산자 정의]


위 연산자들을 정의할 때 <=, >=, <> 사이에 스페이스를 넣으면 안됩니다. 

스페이스를 넣을 경우 별도의 연산자라고 판단하여 에러가 발생합니다.

반응형

+ Recent posts