SQL에서 사용되는 쿼리에는 유용하게 사용할 수 있는 함수가 많다. 그 중 자주 사용하는 몇 가지를 아래의 음원 판매 웹사이트의 스키마의 예시를 분석해보면서 사용해보자.
데이터를 조회할 때 그룹으로 묶어서 조회한다. 다음과 같은 쿼리가 있다고 가정해보자.
-- customers 테이블의 모든 레코드를 조회
SELECT * FROM customers;
-- customers 테이블의 모든 레코드를 State에 따라 그룹화
SELECT * FROM customers
GROUP BY State;
GROUP BY
쿼리로 간단하게 State에 따라 그룹화 할 수 있다. 쿼리의 결과를 확인하면, 데이터가 중간에 비어있는 것을 확인할 수 있다. 데이터베이스에서 데이터를 불러오는 과정에서 State에 따라 그룹을 지정했지만, 그룹에 대한 작업 없이 조회만 했다. 그래서 쿼리의 결과로 나타나는 데이터는 각 그룹의 첫 번째 데이터만 표현된다.
HAVING
은 GROUP BY
로 조회된 결과를 필터링 할 수 있다.
다음의 쿼리를 살펴보자.
-- invoices 테이블을 CustomerId로 그룹화 하고 그 평균이 6을 초과한 결과를 조회
SELECT CustomerId, AVG(Total)
FROM invoices
GROUP BY CustomerId
HAVING AVG(Total) > 6.00
이 쿼리는 모든 고객의 주문서에서 가격의 평균을 구한 뒤에, 그 평균이 6.00을 넘는 결과만 조회한다.
이렇게 GROUP BY로 그룹을 지은 결과에 필터를 적용할 때
HAVING
을 사용할 수 있다.
HAVING
은 WHERE
과는 적용하는 방식이 다르다. HAVING
은 그룹화한 결과에 대한 필터이고, WHERE
는 저장된 레코드를 필터링한다. 따라서 실제로 그룹화 전에 데이터를 필터해야 한다면, WHERE
을 사용한다.
GROUP BY
로 그룹화 하는 방법을 학습했다. 이어서 그룹에 대해 어떤 작업을 할 ㅅ 있는지 확인한다.
COUNT
함수는 레코드의 갯수를 헤아릴 때 사용한다. COUNT
함수의 사용법은 다음과 같다.
-- 모든 레코드에 대한 COUNT 함수 사용 예시
SELECT *, COUNT(*) FROM customers
GROUP BY State;
위 커맨드를 실제로 실행하면, 각 그룹의 첫 번째 레코드와 각 그룹의 레코드 갯수를 집계하여 리턴한다. 아래와 같이 변경하면, 그룹으로 묶인 결과의 레코드 갯수를 확인할 수 있다.
-- 각 State에 해당하는 레코드의 갯수를 확인하는 COUNT 함수 예시
SELECT State, COUNT(*) FROM customers
GROUP BY State;
SUM
함수는 레코드의 합을 리턴한다. SUM
함수의 사용법은 아래와 같다.
-- SUM 함수 사용 예씨
SELECT InvoiceId, SUM(UnitPrice)
FROM invoice_items
GROUP BY InvoiceId;
AVG
함수는 레코드의 평균값을 계산하는 함수이다. AVG
함수의 사용법은 다음과 같다.
-- AVG 함수 사용 예시
SELECT TrackId, AVG(UnitPrice)
FROM invoice_items
GROUP BY TrackId;
MAX
함수와 MIN
함수는 각각 레코드의 최댓값과 최솟값을 리턴한다. 이 함수들은 다음과 같이 사용한다.
-- MIN 함수 사용 예시
SELECT CustomerId, MIN(Total)
FROM invoices
GROUP BY CustomerId
데이터를 조회하는 SELECT
문은 정해진 순서대로 동작한다.
SELECT
문의 실행 순서는 다음과 같다.
아래 예시와 함께 살펴보자.
-- SELECT 문의 실행 순서 예시
SELECT CustomerId, AVG(Total)
FROM invoices
WHERE CustomerId >= 10
GROUP BY CustomerId
HAVING SUM(Total) >= 30
ORDER BY 2
위 쿼리문의 실행 순서는 다음과 같다.
① FROM invoices
: invoices 테이블에 접근한다.
② WHERE CustomerId >= 10
: CustomerId 필드가 10 이상인 레코드들을 조회한다.
③ GROUP BY CustomerId
: CustomerId를 기준으로 그룹화한다.
④ HAVING SUM(Total) >= 30
: Total 필드의 총합이 30 이상인 결과만 필터링한다.
⑤ SELECT CustomerId, AVG(Total)
: 조회된 결과에서 CustomerId 필드와 Total 필드의 평균값을 구한다.
⑥ ORDER BY 2
: AVG(Total)
필드를 기준으로 오름차순 정렬한 결과를 리턴한다.