SQL 데이터베이스에 대해 제대로 알자(7) - 집계함수

BackEnd

지난포스팅 목록

1편(데이터베이스)

2편(조건조합)
3편(정렬)

4편(연산)

5편(추가,삭제,갱신)
6편(논리삭제와 물리삭제)에 이어서 7편에서는 집계에 대해서 배워보자


<집계함수>

 

COUNT로 행 개수 구하기

 

지금부터 집계함수를 사용하는 방법에 대해 알아보도록 하자

 

대표적으로 집계함수는 다음과 같은 5개를 꼽을 수 있다.

 

COUNT(집합)

SUM(집합)

AVG(집합)

MIN(집합)

MAX(집합)

 

SQL은 데이터베이스라 불리는 '데이터 집합'을 다루는 언어이다. 이 같은 집합의 개수나 합계가 궁금하다면 SQL이 제공하는 집계함수를 사용하여 간단하게 구현할 수 있다.

 

그렇다면 먼저 COUNT 집계함수를 사용해서 테이블의 행 개수를 구해보자

 

SQL은 집합을 다루는 집계함수를 제공한다. 일반적인 함수는 인수로 하나의 값을 지정하는 데 비해 집계함수는 인수로 집합을 지정한다. 

 

이 때문에 집합함수라고도 불린다. 즉, 집합을 특정 방법으로 계산하여 그 결과를 반환한다.

 

방금 '함수의 인자로 집합을 지정한다'고 설명했는데, 이해를 돕기 위해 집계함수 COUNT로 예를 들어 설명해보겠다.

 

COUNT 함수는 인수는 인수로 주어진 집합의 '개수'를 구해 반환한다. 

COUNT (집합)

select * from testsql;

이렇게 테이블안에 값이 있다고 해보자

 

SELECT COUNT(*) FROM testsql;

행 개수를 구하는 명령문을 실행해보자

 

이렇게 총 5개의 행에 대한 개수가 총합으로 구해져서 나타났다.

 

여기서 인수가 *로 되어있는데 이는 SELECT 구에서 '모든 열'을 나타내는 메타문자와 같다.

 

다만 이때 COUNT 집계함수에서는 '모든 열 = 테이블 전체' 라는 의미로 사용된다.

 

즉, COUNT는 인수로 지정된 집합(이 경우는 테이블 전체)의 개수를 계산하는 것이다. 

 

현재 테이블에는 5개의 행이 있으므로 그 결과 5가 반환되었다.

 

집계함수의 특징은 복수의 값(집합)에서 하나의 값을 계산해내는 것이다. 일반적인 함수는 하나의 행에 대하여 하나의 값을 반환한다.

 

한편 집계함수는 집합으로부터 하나의 값을 반환한다. 이렇게 집합으로부터 하나의 값을 계산하는 것을 '집계'라고 부른다.

 

이러한 이유로 집계함수를 SELECT 구에 쓰면 WHERE 구의 유무와 관계없이 결괏값 하나의 행을 반환한다.

 

WHERE 구 지정하기

정말 하나의 행만 반환되는지 한번 실험해보자

 

현재 5개의 행이 존재하는 testsql테이블에서 name 열이 A인 행을 검색하여 COUNT로 행의 개수를 구해보자

 

현재 name 열이 A인 행의 개수는 2개로, 각각의 no 값이 1과 2가된다. 이때 COUNT를 사용하면 어떻게 될까?

 

SELECT * FROM testsql WHERE name = 'A';
SELECT COUNT(*) FROM testsql WHERE name = 'A';

결과 행은 역시 오직 하나뿐이다.

 

SELECT 구는 WHERE 구보다 나중에 내부적으로 처리된다. 따라서 WHERE 구로 조건을 지정하면 테이블 전체가 아닌, 검색된 행이 COUNT로 넘겨진다. 즉, WHERE 구의 조건에 맞는 행의 개수를 구할 수 있다. 앞의 예시에서도 검색된 행은 두 개였지만, 최종적으로는 하나의 행이 되었다.

 

그러니까 먼저 실행되는 순서를 알아야한다.

 

WHERE 구가 먼저 실행 -> SELECT 구가 실행됨

 

WHERE 구에서 조건을 name이 A인 것으로 걸어서 해당하는 2개의 행을 뽑아냄 -> 그리고 그 행에 개수를 SELECT에서 COUNT를 돌려서 결괏값을 뽑아낸다. 그래서 최종적으로 결괏값은 2가 된다.

 

 

집계함수와 NULL값

 

COUNT의 인수로 열명을 지정할 수 있다. 열명을 지정하면 그 열에 한해서 행의 개수를 구할 수 있다. 

실제로 집계함수는 보통 그런 목적을 위해 많이 사용된다. 특히 *을 인수로 사용할 수 있는 것은 COUNT 함수뿐이다.

 

다른 집계함수는 열명이나 식을 인수로 지정한다.

 

여기서 문제는 NULL값을 어떻게 취급하느냐 하는 것이다. 이전에도 언급했듯이 SQL에서는 NULL값을 고려해야 한다.

 

집계함수는 집합 안에 NULL 값이 있을 경우 이를 제외하고 처리한다.

 

그럼 테이블을 사용하여 알아보도록 하자 이 테이블의 no 열에는 NULL값이 없지만 name 열에는 NULL 값이 존재한다.

 

select * from testsql;

 

SELECT COUNT(no), COUNT(name) FROM testsql;

 

no 열의 행 개수는 5, name 열의 행 개수는 4로 나타났다. name열에는 NULL값을 가지는 행이 하나 존재하므로,

이를 제외한 개수는 4가 된다.

 

다만 COUNT(*)의 경우 모든 열의 행수를 카운트하기 때문에 NULL값이 있어도 해당 정보는 무시되지 않는다.

 

실제로 COUNT(*)을 해보면 알 수 있다.

 

SELECT COUNT(*) FROM testsql;

 

Point -> COUNT(*)이 아닌 열명을 지정할 경우 집계함수는 집합 안에 NULL 값이 있을 경우 무시한다!

 

DISTINCT로 중복제거

 

집합을 다룰 때, 경우에 따라서는 집합 안에 중복된 값이 있는지 여부가 문제가 될 때도 있다.

데이터가 서로 중복되지 않는 경우에는 '유일한 값을 가진다'라든가 '값이 중복되지 않는다'라는 표현을 자주한다.

 

말보다는 테이블에서 나왔던 값으로 설명을 해보자

 

select * from testsql;

여기보면 현재 1번과 2번에 해당하는 name은 A라는 값으로 중복된다.

 

no 열은 1, 2, 3....과 같이 일련의 숫자로 되어 있으므로 각 행의 값은 중복되지 않는다.

 

한편 name 열의 값은 맨 위에 두 줄이 중복된다.

 

SQL SELECT 명령은 이러한 중복된 값을 제거하는 함수를 제공한다. 이때 사용하는 키워드가 바로 DISTINCT이다. 

 

SELECT ALL name FROM testsql;

 

이렇게 name 열의 값을 다 뽑아봤다.

 

여기서 중복된 값을 제거해보자

 

SELECT DISTINCT name FROM testsql;

 

환상적이다. 아주 잘 제거되었다!

 

DISTINCT는 예약어로 열명이 아니다. SELECT 구에서 DISTINCT를 지정하면 중복된 데이터를 제외한 결과를 클라이언트로 반환한다.

 

중복 여부는 SELECT 구에 지정된 모든 열을 비교해 판단한다.

 

이전 예제에서는 첫 번째 SELECT 명령에서는 DISTINCT가 아닌 ALL을 지정했다.

 

이렇게 하면 중복 유무와 관계없이 문자 그대로 모든 행을 반환한다. 즉, SELECT 구에 지정하는 ALL 또는 DISTINCT는 중복된 값을 제거할 것인지 설정하는 스위치와 같은 역할을 한다. 이때 ALL과 DISTINCT 중 어느 것도 지정하지 않은 경우에는 중복된 값은 제거되지 않는다. 즉, 생략할 경우에는 ALL로 간주한다.

 

집계함수에서 DISTINCT

 

COUNT 집계함수를 이용해 집합의 개수를 구하는 방법을 살펴보았다. 그리고 DISTINCT를 지정하면 중복된 값을 제거할 수 있다는 것도 알게되었다. 그렇다면 이번에는 name열에서 NULL 값을 제외하고, 중복하지 않는 데이터의 개수(A, B, C 3개)를 구하는 경우를 생각해보자. COUNT 함수, DISTINCT, WHERE 구의 조건을 지정해 구할 수 있는지 잠깐 생각해보자

 

정답은? 할 수 없다!

 

WHERE 구에서는 검색할 조건을 지정하는 것 밖에 할 수 없다. 중복된 값인지 아닌지를 알아보는 함수도 없다. 

SELECT DISTINCT COUNT(name)이라는 SELECT 명령으로도 안된다. COUNT 쪽이 먼저 계산되어버리기 때문이다.

 

어떻게 하면 좋을까?

 

방법은 집계함수의 인수로 DISTINCT를 사용한 수식을 지정하는 것이다.

 

DISTINCT는 집계함수의 인수에 수식자로 지정할 수 있다. DISTINCT를 이용해 집합에서 중복을 제거한 뒤 COUNT로 개수를 구할 수 있게되는 것이다. 그럼 실제로 되는지 어디한번 해보자!

 

현재 테이블 데이터를 먼저 보여주면

select * from testsql;

 

 

현재 이렇게 테이블 데이터가 존재한다. 이제 그럼 한번 명령을 때려보자!

SELECT COUNT(ALL name), COUNT(DISTINCT name) FROM testsql;

SELECT 구에서 중복삭제와 마찬가지로, DISTINCT가 아닌 ALL을 지정하면 집합 전부가 집계함수에 주어진다.

앞서 설명했듯이 ALL을 생략해도 결과는 같다. 이때 DISTINCT와 ALL은 인수가 아니므로 콤마는 붙이지 않는다.

 

COUNT 이외의 집계함수

 

집계함수는 COUNT만 있는 것이 아니다. SUM 집계함수를 사용해 집합의 합계치를 구할 수 있다. 

이번에는 COUNT 이외의 집계함수에 관해 알아볼 생각이다.

 

SUM 집합

AVG 집합

MIN 집합

MAX 집합

 

 

집합을 연산할 때 자주 사용하는 것이 바로 합계이다. 통상적으로 프로그래밍 언어를 사용하는 경우에는 반복처리를 통해 합계를 구하지만 

SQL에서는 SUM 함수를 사용해 합계를 구할 수 있다.

 

또한 집합에서 최솟값, 최댓값을 찾는 경우에도 집계함수를 사용해 처리할 수 있다.

 

SUM으로 합계 구하기

 

집계 함수는 COUNT만 있는 것이 아니다. SUM 집계함수를 사용해 집합의 합계를 구할 수 있다.

 

예를 들어 1, 2, 3이라는 세 게의 값을 가지는 집합이 있다고 하자.

 

SUM 집계함수의 인수로 이 집합을 지정하면 1+2+3으로 계산하여 6이라는 값을 반환한다.

 

그럼 지금부터 테이블을 보면서 SUM으로 합계를 구해보자 

 

SELECT * FROM testsql;

 

SELECT SUM(quantity) FROM testsql;

 

SUM 집계함수에 지정되는 집합은 수치형이다. 문자열형이나 날짜시간형의 집합에서 합계를 구할수는 없다.

name열은 문자열형이므로 SUM(name)과 같이 지정할 수는 없다. 

 

한편, SUM 집계함수도 COUNT와 마찬가지로 NULL 값을 무시한다. NULL 값을 제거한 뒤에 합계를 낸다.

 

AVG로 평균내기

SUM 집계함수를 사용하여 집합의 합계를 구할 수 있었다. 이때 합한 값을 개수로 나누면 평균값을 구할 수 있다.

집계함수가 반환한 값을 연산할 수도 있는데 SUM(quantity) / COUNT(quantity)와 같이 지정하면 된다.

 

하지만 굳이 SUM과 COUNT를 이용하지 않더라도, AVG라는 집계함수를 통해 평균값을 간단하게 구할 수 있다.

AVG 집계함수에 주어지는 집합은 SUM과 동일하게 수치형만 가능하다.

 

SELECT * FROM testsql;

 

SELECT AVG(quantity), SUM(quantity)/COUNT(quantity)FROM testsql;

간단하게 AVG로 구하는 방법도 있다.

 

SELECT AVG(quantity) FROM testsql;


AVG 집계함수도 NULL 값은 무시한다. 즉 NULL 값을 제거한 뒤에 평균값을 계산한다. 만약 NULL을 0으로 간주해서 평균을 내고 싶다면 CASE를 사용해 NULL을 0으로 변환한 뒤에 AVG함수로 계산하면 된다.

SELECT AVG(CASE WHEN quantity IS NULL THEN 0 ELSE quantity END) AS avgnull0 FROM testsql;

MIN MAX 최솟값 최댓값 구하기

 

MIN 집계함수, MAX 집계함수를 사용해 집합에서 최솟값과 최댓값을 구할 수 있다.

이들 함수는 문자열형과 날짜시간형에도 사용할 수 있다. 다만 NULL 값을 무시하는 기본규칙은 다른 집계함수와 같다.

 

SELECT * FROM testsql;
SELECT MIN(quantity), MAX(quantity), MIN(name), MAX(name) FROM testsql;

이렇게 각 열에서 문자열은 ABC순서로 숫자는 1...100 순서를 기준으로 했을 때

 

가장 작은 값(수) 가장 큰 값(수)를 데이터로 나타낼 수 있다.

그룹화 - GROUP BY

 

이번에는 GROUP BY 구를 사용해서 그룹화하는 방법에 대해 알아보자

 

그룹화를 통해 집계함수의 활용범위를 넓힐 수 있다.

 

SELECT * FROM testsql GROUP BY name, quantity;

앞에서 COUNT 함수로 행 개수를 구할 수 있었다. COUNT 인수로는 집합을 지정하였는데 이제까지 봐온 예제에서는 테이블 전체 혹은

WHERE 구로 검색한 행이 그 대상이었다.

 

지금부터는 GROUP BY 구를 사용해 집계함수로 넘겨줄 집합을 그룹으로 나누는 방법에 대해 배워보자

 

이 같은 그룹화를 통해 집계함수의 활용범위를 넓힐 수 있다. 먼저 그룹화에 관해 간단히 살펴보고, 조건을 지정하거나 정렬하여 사용하는 법에 관해 알아보자

 

GROUP BY로 그룹화

 

GROUP BY 구로 그룹화하기에 앞서 테이블의 내용을 다시 확인해보자 name 열을 주의깊게 봐보자

 

name 열이 A인 행은 두 개, B와 C인 행은 각각 한 개씩 있다. name 열에서 같은 값을 가진 행끼리 묶어 그룹화한 집합을 집계함수로 넘겨줄 수 있다. 그룹으로 나눌 때는 GROUP BY 구를 사용한다. 

 

이때 GROUP BY구에는 그룹화할 열을 지정한다. 물론 복수로도 지정할 수 있다. 예를 들어 name 열을 지정하면 어떤 결과가 나오는지 알아보자

 

SELECT name FROM testsql GROUP BY name;

DISTINCT를 지정했을 때와 같은 결과가 나왔다. GROUP BY 구에 열을 지정하여 그룹화하면 지정된 열의 값이 같은 행이 하나의 그룹으로 묶인다. 

 

SELECT 구에서 name열을 지정하였으므로 그룹화된 name 열의 데이터가 클라이언트로 반환된다.

 

각 그룹으로 묶인 값들은 서로 동일하다. 즉, 결과적으로 각각의 그룹 값이 반환된다. 

 

따라서 GROUP BY를 지정해 그룹화하면 DISTINCT와 같이 중복을 제거하는 효과가 있다. 

 

결론적으로 A가 2개이지만 중복이 제거되어서 A는 1개만 남는 것이다.

 

그럼, DISTINCT로 중복을 제거하는 것과 GROUP BY로 그룹화하는 것은 어떤 차이가 있을까? 

 

실은 GROUP BY 구를 지정하는 경우에는 집계함수와 함께 사용하지 않으면 별 의미가 없다. GROUP BY 구로 그룹화된 각각의 그룹이 하나의 집합으로 집계함수의 인수로 넘겨지기 때문이다. 

 

구체적으로 어떻게 처리되는지 테이블을 보면서 확인해보자

 

그리고 COUNT와 SUM 집계함수를 사용해서 알아보자 

 

SELECT name, COUNT(name), SUM(quantity) FROM testsql GROUP BY name;

GROUP BY name에 의해 name 열 값이 A, B, C 그리고 NULL의 네 개 그룹으로 나뉜다.

 

A 그룹에는 두 개의 행이 있는데, COUNT는 행의 개수를 반환하므로 2가 된다.

A 그룹에 해당하는 2개의 행의 quantity 열 값은 각각 1과 2가 된다. SUM은 합계를 구하는 집계함수이므로 3을 반환한다.

 

사실 지금보이는 예시는 설명하기 위해서 임의로 준비한 테이블이므로, 실제로는 어떤 경우에 쓰이는지 잘 이해가 가지 않을 수 있다.

 

그럼, 실제로 GROUP BY를 사용하는 경우를 간단하게 소개해보겠다.

 

업무환경에서 GROUP BY를 사용하는 경우는 꽤 많다. 예를 들면 각 점포의 일별 매출 데이터가 중앙 판매 관리시스템에 전송되어 점포별 매출실적을 집계해 어떤 점포가 매출이 올라가는지, 어떤 상품이 인기가 있는지 등을 분석할 때 사용된다.

 

여기에서 점포별, 상품별, 월별, 일별 등 특정 단위로 집계할 때 GROUP BY를 자주 사용한다.

 

매출실적을 조사하는 동시에 SUM 집계함수로 합계를 낼 수 있으며, COUNT로 건수를 집계하는 경우도 있다.

 

HAVING 구로 조건 지정

 

집계함수는 WHERE 구의 조건식에서는 사용할 수 없다. 실제로 그러한지 다음 명령어를 통해 확인해보자

 

SELECT name, COUNT(name) FROM testsql WHERE COUNT(name)=1 GROUP BY name;

name 열을 그룹화하여 행 개수가 하나만 존재하는 그룹을 검색하고 싶었지만 에러가 발생하여 실행할 수 없다.

에러가 발생한 이유는 GROUP BY와 WHERE 구의 내부처리 순서와 관계가 있다. 즉 WHERE 구로 행을 검색하는 처리가 GROUP BY로 그룹화하는 처리보다 순서상 앞서기 때문이다.

 

SELECT 구에서 지정한 별명을 WHERE 구에서 사용할 수 없었던 것과 같은 이유로, 그룹화가 필요한 집계함수는 WHERE구에서 지정할 수 없다.

 

내부처리 순서 : 

 

WHERE 구 -> GROUP BY 구 -> SELECT 구 -> ORDER BY 구

Point -> WHERE 구에서는 집계함수를 사용할 수 없다!

 

그렇다면 집계한 결과에서 조건에 맞는 값을 따로 걸러낼 수는 없는 걸까? 물론 가능하다. SELECT 명령에는 HAVING 구가 있다.

 

HAVING 구는 GROUP BY 구의 뒤에 기술하며 WHERE 구와 동일하게 조건식을 지정할 수 있다. 조건식에는 그룹별로 집계된 열의 값이나 집계함수의 계산결과가 전달된다고 생각하면 이해하기 쉽다. 이때 조건식이 참인 그룹값만 클라이언트에게 반환된다.

 

결과적으로 WHERE 구와 HAVING 구에 지정된 조건으로 검색하는 2단 구조가 되는 것이다.

 

그러면, 앞서 에러가 발생했던 SELECT 명령을 HAVING 구를 사용해 수정해보자

 

SELECT name, COUNT(name) FROM testsql GROUP BY name;

HAVING 구로 걸러내기

 

SELECT name, COUNT(name) FROM testsql GROUP BY name HAVING COUNT(name) =1;

그룹화보다도 나중에 처리되는 ORDER BY 구에서는 문제없이 집계함수를 사용할 수 있다.

 

즉, ORDER BY COUNT(name)과 같이 지정할 수 있다.

 

지금부터는 HAVING 구의 내부처리 순서에 대해서 설명해보겠다. HAVING 구는 GROUP BY 구 다음으로 처리된다.

 

내부처리 순서

 

WHERE 구 -> GROUP BY -> HAVING 구 -> SELECT 구 -> ORDER BY 구

 

다만 SELECT 구보다도 먼저 처리되므로 별명을 사용할 수는 없다. 예를 들어 COUNT(name)에 cn 이라는 별명을 붙이면, ORDER BY 구에서는 사용할 수 있지만 GROUP BY 구에서는 사용할 수 없다.

 

즉, 다음과 같은 명령은 실행할 수 없지만 MySQL에서는 실행할 수 있고 Oracle 등에서는 에러가 발생한다.

 

SELECT name AS n, COUNT(name) AS cn FROM testsql GROUP BY n HAVING cn=1;

MySQL 결과값은 이렇게 나온다.

 

복수열의 그룹화

 

GROUP BY를 사용할 때 주의할 점이 하나 더 있다. GROUP BY에 지정한 열 이외의 열은 집계함수를 사용하지 않은 채 SELECT 구에 기술해서는 안된다는 것이다. 

 

더 자세히 알아보기 위해서 예시를 보여주자면,

 

SELECT no, name, quantity FROM testsql GROUP BY name;

 

여기서 no, quantity는 지정할 수 없다. 

 

GROUP BY로 그룹화하면 클라이언트로 반환되는 결과는 그룹당 하나의 행이된다. 

 

하지만 name 열 값이 A인 그룹의 quantity 열 값은 1과 2로 두개이다. 

 

이때 그룹마다 하나의 값만을 반환해야 하므로 어느 것을 반환하면 좋을지 몰라 에러가 발생한다.

 

이때 집계함수를 사용하면 집합은 하나의 값으로 계산되므로, 그룹마다 하나의 행을 출력할 수 있다.

 

즉 다음과 같이 쿼리를 작성하면 문제없이 실행할 수 있다. 

 

SELECT MIN(no), name, SUM(quantity) FROM testsql GROUP BY name;

 

 

이렇게 값이 나오고 있다.

기존에 테이블 값은 이렇게 되어있는데

 

위에서 내린 명령을 다시보면서

SELECT MIN(no), name, SUM(quantity) FROM testsql GROUP BY name;

해석해보면 name으로 그룹화를 하는데 quantity는 전부다 더해주고 no는 가장 작은수를 기준으로 데이터를 보여줘! 라는 것이다.

 

그래서 name으로 그룹화를 해서 중복된 1번 A와 2번 A를 하나로 합친 것이다. 그리고 no는 2개를 합칠 때 MIN으로 가장 작은 수를 가져오기때문에 1과 2를 비교해서 작은 수 1을 가져오게 되고 quantity같은 경우 SUM으로 합을 가져오게 했으니 기존에 합치기전에 있던

1과 2를 더한 3이라는 값을 가져오게 된다. 그리고 B와 C는 기존 값에서 변경될 상황이 없기 때문에 있는 값이 그대로 옮겨지게 된다.

 

그리고 마지막으로 NULL은 제외되는 것이다.

 

만약 no와 quantity로 그룹화를 한다면 GROUP BY no, quantity로 지정한다.

 

이처럼 GROUP BY에서 지정한 열이라면 SELECT 구에 그대로 지정해도 된다.

 

SELECT no, quantity FROM testsql GROUP BY no, quantity;

 

이 코드는 말그대로 기존 테이블에 있는 3개의 열(no, name, quantity)중에 2개(no, quantity)를 그룹화해서 조회해달라는 명령이다.

 

결괏값 정렬

 

GROUP BY로 그룹화해도 실행결과 순서를 정렬할 수는 없다. 데이터베이스 내부 처리에서 같은 값을 그룹으로 나누는 과정에서 

순서가 서로 바뀌는 부작용이 일어날 수 있기 떄문이다. 하지만 이는 데이터베이스 내부처리의 문제로 데이트베이스 제품에 따라 다르다.

 

확실한 것은 GROUP BY 지정을 해도 정렬되지 않는다는 점이다.

 

이럴 때는 이전에 설명한 것처럼 ORDER BY 구를 사용해서 결과를 정렬할 수 있다. 

 

GROUP BY 구로 그룹화한 경우에도 ORDER BY 구를 사용해 정렬할 수 있다. 

 

결괏값을 순서대로 정렬해야 한다면 ORDER BY 구를 지정하면 된다.

 

집계한 결과 정렬하기 : 

name열로 그룹화해 합계를 구하고 내림차순으로 정렬해보자

SELECT name, COUNT(name), SUM(quantity) FROM testsql GROUP BY name ORDER BY SUM(quantity) DESC;

합계를 구한 뒤 분석할 때는 값이 큰 순서대로 살펴보고 싶을 것이다. 이때 내림차순으로 정렬하기 위해서 'DESC'를 지정했다.

 

기본값이 ASC이므로 DESC를 지정하지 않으면 오름차순이 되어버린다. 이와 같은 경우는 자주 있는 패턴으로 잊어버리지 않도록 하자

 

이것으로 집계가 무엇인지 알아보았다. 이쯤에서 한번 끊어주고 다음편에서는 서브쿼리가 무엇인지에 대해 알아보도록 하자

 

새벽1시가 넘어서야 정리가 끝이 났는데, 책을 읽으면서 공부하고 실습하고 정리까지 하려니까 진도가 확실히 늦다.

 

내일까지는 책을 다 정리하고 주말동안 CRUD, JOIN , 그룹화 등등 업무에 능숙하게 적용할 수 있을 수준이 되도록

주말동안 강도높게 공부해서 이 책에서 배운 것들을 모두 내것으로 만들어야겠다.

 

하고싶은 말들이 많지만 속으로 삼키고 실력으로 내뱉고 싶다.

 

여기까지 혹시라도 이어서 보고 계신 분이 있을지 모르겠지만,

 

부족한 정리글을 꾸준히 읽어주셔서 감사함을 표한다.

 

 

 

모든 포스팅에 대한 내용은 도서 SQL첫걸음에서 익히고 배운 것들에 대한 내용을 직접 타이핑 하였음을 밝힙니다.