본문 바로가기

SQL

[SQL] SQL SELECT 문(2)

목차

  • ORDER BY 절
  • LIMIT
  • DISTINCT
  • GROUP BY 절
  • 집계 함수
  • HAVING 절

 

정렬을 위한 SELECT 문

SELECT 문에서는 결과의 정렬을 위한 ORDER BY

결과의 개수를 제한하는 LIMIT

중복된 데이터를 제거하는 DISTINCT 등이 있다.

 

그리고 GROUP BY 절은 지정한 열의 데이터들을 같은 데이터끼리는 묶어서 결과를 추출한다.

주로 그룹을 묶는 경우는 합계, 평균, 개수 등을 처리할 때 사용하므로 집계 함수와 함께 사용한다.

GROUP BY 절에서도 HAVING 절을 통해 조건식을 추가할 수 있다.

HAVING 절은 WHERE 절과 비슷해 보이지만, GROUP BY 절과 함께 사용되는 것이 차이점이다.

 

ORDER BY 절

SELECT 절의 형식은 다음과 같다.

SELECT 열_이름
    FROM 테이블_이름
    WHERE 조건식
    GROUP BY 열_이름
    HAVING 조건식
    ORDER BY 열_이름
    LIMIT 숫자

 

ORDER BY 절은 결과의 값이나 개수에 대해서는 영향을 미치지 않지만, 결과가 출력되는 순서를 조절한다.

 

예시: 데뷔 일자(debut_date)가 빠른 순서대로 출력

SELECT mem_id, mem_name, debut_date
    FROM member
    ORDER BY debut_date;

 

데뷔 일자(debut_date)가 늦은 순서대로 정렬하려면 DESC라고 붙여주면 된다.

기본 값은 ASC인데 Ascending의 약자로 오름차순을 의미하고, DESC는 Descending의 약자로 내림차순을 의미한다.

SELECT mem_id, mem_name, debut_date
    FROM member
    ORDER BY debut_date DESC;

 

ORDER BY 절과 WHERE 절은 함께 사용할 수 있다.

평균 키(height)가 164 이상인 회원들을 키가 큰 순서대로 조회해보겠다.

참고로 ORDER BY 절은 WHERE 절 다음에 나와야 한다.

SELECT mem_id, mem_name, debut_date, height
    FROM member
    WHERE height >= 164
    ORDER BY height DESC;

SELECT 문에 나오는 절은 생략 가능하지만, 사용해야 한다면 순서를 지켜야 한다.

 

정렬 기준은 1개 열이 아니라 여러 개 열로 지정할 수 있다.

우선 첫 번째 지정 열로 정렬한 후에 동일할 경우에는 다음 지정 열로 정렬할 수 있다.

즉, 평균 키가 큰 순서대로 정렬하되, 평균 키가 같으면 데뷔 일자가 빠른 순서로 정렬한다.

SELECT mem_id, mem_name, debut_date, height
    FROM member
    WHERE height >= 164
    ORDER BY height DESC, debut_date ASC;

데뷔 순서대로 아주 잘 바뀐 모습!

 

 

 

LIMIT

 

LIMIT은 출력하는 개수를 제한한다.

예를 들어, 회원 테이블을 조회하는데 전체 중 앞에서 3건만 조회할 수 있다.

SELECT *
    FROM member
    LIMIT 3;

 

결과에는 문제가 없지만, 이렇게 아무런 기준 없이 앞에서 3건만 뽑는 경우는 별로 없다.

먼저 정렬한 후 앞에서 몇 건을 추출하는 것이 대부분이다.

예를 들어, 데뷔 일자(debut_date)가 빠른 회원 3건만 추출하려면 다음과 같이 ORDER BY와 함께 사용할 수 있다.

 

LIMIT 형식은 LIMIT 시작, 개수 이다.

지금과 같이 LIMIT  3만 쓰면 LIMIT 0, 3과 동일하다.

SELECT *
    FROM member
    ORDER BY debut_date
    LIMIT 0, 3;

 

필요하다면 중간부터 출력도 가능하다.

평균 키(height)가 큰 순으로 정렬하되, 3번째부터 2건만 조회

SELECT mem_name, height
    FROM member
    ORDER BY height DESC
    LIMIT 3, 2;

 

LIMIT 시작, 개수LIMIT 개수 OFFSET 시작이라고 쓰는 것과 동일하다.

SELECT mem_name, height
    FROM member
    ORDER BY height DESC
    LIMIT 2 OFFSET 3;

 

 

 

 

 

DISTINCT

DISTINCT는 조회된 결과에서 중복된 데이터를 1개만 남긴다.

여기서 회원들의 지역(addr)을 출력해보겠다.

 

SQL 문의 결과를 보면 중복된 것을 눈으로 골라내기가 어렵다.

 

그래서 ORDER BY를 사용해보겠다.

 

같은 지역이 몰려 있어서 아까보다는 세기가 쉽지만 데이터가 많다면 현실적으로 종류를 세는 것은 힘들다.

이를 간단하게 하는 것이 DISTINCT 문이다. 열 이름 앞에 DISTINCT를 써주기만 하면 중복된 데이터를

1개만 남기고 제거한다.

SELECT DISTINCT addr
    FROM member
    ORDER BY addr;

 

 

 


GROUP BY 절

 

 

GROUP BY 절은 말 그대로 그룹으로 묶어주는 역할을 한다.

다음 SQL 문을 사용하면 market_db의 구매 테이블(buy)에서

회원(mem_id)이 구매한 물품의 개수(amount)를 구할 수 있다.

SELECT mem_id, amount FROM buy GROUP BY mem_id;

APN(에이핑크) 회원의 경우 총 5개의 물건을 구매했다.

그런데 합계를 이렇게 암산이나 계산기로 계산해야 한다면 MySQL을 사용할 이유가 없을 것이다.

이럴 때는 집계 함수를 사용하면 된다.

집계 함수는 주로 GROUP BY 절과 함께 쓰이며 데이터를 그룹화(grouping) 해주는 기능을 한다.

 

 

집계 함수

GROUP BY 와 함께 주로 사용되는 집계 함수이다.

 

각 회원(mem_id) 별로 구매한 개수(amount)를 합쳐서 출력하기 위해서는

집계 함수인 SUM( )과 GROUP BY절을 사용하면 된다.

즉, GROUP BY로 회원별로 묶어준 후에 SUM( ) 함수로 구매한 개수를 합치면 된다.

SELECT mem_id, SUM(amount) FROM buy GROUP BY mem_id;

 

별칭(alias)을 사용해서 이쁘게 결과를 만들 수도 있다.

별칭에 작은따옴표를 사용해도 되지만, 작은따옴표는 INSERT등에서 문자를 입력할 때 사용하므로 큰 따옴표를 권장한다.

SELECT mem_id "회원 아이디", SUM(amount) "총 구매 개수" 
    FROM buy GROUP BY mem_id;

 

 

이번에는 회원이 구매한 금액의 총합을 출력해보겠다.

구매한 금액은 가격(price) * 수량(amount) 이다.

SELECT mem_id "회원 아이디", SUM(price * amount) "총 구매 개수" 
    FROM buy GROUP BY mem_id;

 

전체 회원이 구매한 물품 개수(amount)의 평균도 구할 수 있다.

즉, 회원이 한 번 구매할 때마다 평균 몇 개를 구매하는지 알아보는 것이다.

SELECT AVG(amount) FROM BUY;

 

이번에는 각 회원이 한 번 구매 시 평균 몇 개를 구매했는지 알아보겠다.

회원(mem_id)별로 구해야 하므로 GROUP BY를 사용하면 된다.

SELECT mem_id, AVG(amount) "평균 구매 개수" 
    from buy 
    GROUP BY mem_id;

 

이번에는 회원 테이블(member)에서 연락처가 있는 회원의 수를 카운트해보겠다.

그런데 결과는 전체 회원 수인 10이 나온다.

SELECT COUNT(*) FROM member;

 

연락처가 있는 회원만 카운트하려면 국번(phone1) 또는 전화번호(phone2)의 열 이름을 지정해야 한다.

SELECT COUNT(phone1) "연락처가 있는 회원" FROM member;

 

 

 

HAVING 절

 

앞에서 살펴보았던 SUM( )으로 회원(mem_id) 별 총 구매액을 구해보겠다.

SELECT mem_id "회원 아이디", SUM(price * amount) "총 구매 금액"
    FROM buy 
    GROUP BY mem_id;

 


결과 중에서 총 구매액이 1000 이상인 회원에게만 사은품을 증정하려면 어떻게 해야할까?

아마도 조건을 포함하는 WHERE 절을 생각했을 것이다.

하지만 실행을 하게되면 집계 함수는 WHERE 절에 나타날 수 없다는 내용이 나온다.

SELECT mem_id "회원 아이디", SUM(price * amount) "총 구매 금액"
    FROM buy 
    WHERE SUM(price * amount) > 1000
    GROUP BY mem_id;

 

 

이럴 때 WHERE 대신 사용되는 것이 HAVING 절이다.

HAVING은 WHERE와 비슷한 개념으로 조건을 제한하는 것이지만, 집계 함수에 대해서 조건을 제한하는 것이다.

그리고 HAVING 절은 꼭 GROUP BY 절 다음에 나와야 한다.

SELECT mem_id "회원 아이디", SUM(price * amount) "총 구매 금액"
    FROM buy 
    GROUP BY mem_id
	HAVING SUM(price * amount) > 1000;

 

 

만약 총 구매액이 큰 사용자부터 나타내려면 ORDER BY를 사용하면 된다.

SELECT mem_id "회원 아이디", SUM(price * amount) "총 구매 금액"
    FROM buy 
    GROUP BY mem_id
    HAVING SUM(price * amount) > 1000
    ORDER BY SUM(price * amount) DESC;

 

'SQL' 카테고리의 다른 글

[SQL] MySQL의 데이터 형식  (0) 2024.05.31
[SQL] 데이터 변경을 위한 SQL 문  (0) 2024.05.31
[SQL] SQL SELECT 문(1)  (0) 2024.05.31
[SQL] 데이터베이스 개체  (0) 2024.05.30
[SQL] 데이터베이스 구축해보기  (1) 2024.05.30