-- 스칼라 서브쿼리 사용
INSERT INTO sample541 VALUES ( (SELECT COUNT(*) FROM sample51), (SELECT COUNT(*) FROM sample54) ); -- INSERT SELECT INSERT INTO sample541 SELECT 1, 2;
UPDATE sample54 SET a = (SELECT MAX(a) FROM sample54);
20강 행 개수 구하기 - COUNT
- 대표적인 집계함수
COUNT (집합)
SUM (집합)
AVG (집합)
MIN (집합)
MAX (집합)
- SQL은 데이터베이스라 불리는 '데이터 집합'을 다루는 언어
1. COUNT로 행 개수 구하기
- SQL은 집합을 다루는 집계함수를 제공
- 집계함수는 인수로 집합을 지정 / 때문에 집합함수라고도 불림 (일반적인 함수는 인수로 하나의 값을 지정)
; 즉, 집합을 특정 방법으로 계산하여 그 결과를 반환
- COUNT 함수는 인수로 주어진 집합의 '개수'를 구해 반환
; 즉, COUNT는 인수로 지정된 집합(이 경우는 테이블 전체)의 개수를 계산하는 것
- 집계함수의 특징은 복수의 값(집합)에서 하나의 값을 계산해내는 것
- 집계함수는 집합으로부터 하나의 값을 반환 (일반적인 함수는 하나의 행에 대하여 하나의 값을 반환)
> 집합으로부터 하나의 값을 계산하는 것을 '집계'라 부름
> 이러한 이유로 집계함수를 SELECT 구에 쓰면 WHERE 구의 유무와 관계없이 결괏값으로 하나의 행을 반환
- WHERE 구 지정하기
; WHERE 구의 조건에 맞는 행의 개수를 구할 수 있음
2. 집계함수와 NULL 값
- COUNT의 인수로 열명을 지정할 수 있음.
> 열명을 지정하면 그 열에 한해서 행의 개수를 구할 수 있음.
(실제로 집계함수는 보통 그 같은 목적을 위해 많이 사용됨)
- 특히 *를 인수로 사용할 수 있는 것은 COUNT 함수뿐. (다른 집계함수에서는 열명이나 식을 인수로 지정)
- 집계함수는 집합 안에 NULL 값이 있을 경우 이를 제외하고 처리.
; 집계함수는 집합 안에 NULL 값이 있을 경우 무시한다!
3. DISTINCT로 중복 제거
<경우에 따라서 집합 안에 중복된 값이 있는지 여부가 문제가 되는 경우>
- SQL의 SELECT 명령은 중복된 값을 제거하는 함수를 제공.
- DISTINCT는 예약어로 열명이 아님.
- SELECT 구에서 DISTINCT를 지정하면 중복된 데이터를 제외한 결과를 클라이언트로 반환. (중복 여부는 SELECT 구에서 지정된 모든 열을 비교해 판단)
- 이때 ALL과 DISTINCT 중 어느 것도 지정하지 않은 경우에는 중복된 값은 제거되지 않음.
; 즉, 생략할 경우에는 ALL로 간주.
4. 집계함수에서 DISTINCT
<name 열에서 NULL 값을 제외하고, 중복하지 않는 데이터의 개수를 구하는 경우>
; 할 수 없음
- DISTINCT을 사용한 수식을 지정하여 해결.
- DISTINCT는 집계함수의 인수에 수식자로 지정할 수 있음.
> DISTINCT를 이용해 집합에서 중복을 제거한 뒤 COUNT로 개수를 구할 수 있음.
21강 COUNT 이외의 집계함수
- SUM 집계함수를 사용해 집합의 합계치를 구할 수 있음.
SUM( [ALL|DISTINCT] 집합)
AVG( [ALL|DISTINCT] 집합)
MIN( [ALL|DISTINCT] 집합)
MAX( [ALL|DISTINCT] 집합)
1. SUM으로 합계 구하기
- SUM 집계함수에 지정되는 집합은 수치형 뿐.
- 문자열형이나 날짜시간형의 집합에서 합계를 구할 수 없음.
예시) name 열은 문자열형이므로 SUM(name)과 같이 지정할 수 없음.
- 한편, SUM 집계함수도 COUNT와 마찬가지로 NULL 값을 무시함. NULL 값을 제거한 뒤에 합계를 냄.
2. AVG로 평균내기
- SUM 집계함수를 사용하여 집합의 합계를 구한 후, 합한 값을 개수로 나누면 평균값을 구할 수 있음.
- 집계함수가 반환한 값을 연산할 수도 있는데 > SUM(quantity) / COUNT (quantity) 와 같이 지정.
; 즉 NULL 값을 제거한 뒤에 평균값을 계산
- NULL을 O로 간주해서 평균을 내고 싶다면 CASE를 사용해 NULL을 0로 변환한 뒤에 AVG 함수로 계산하면 됨.
3. 3. MIN · MAX로 최솟값·최댓값 구하기
22강 그룹화 - GROUP BY
✅ 1. GROUP BY 구로 그룹화
- GROUP BY는 같은 값을 가진 행들을 하나의 그룹으로 묶을 때 사용.
- 집계 함수(COUNT, SUM 등)와 함께 사용하여 각 그룹별로 계산 가능.
- SELECT name FROM sample51 GROUP BY name; 은 DISTINCT name과 같은 결과를 반환함.
- 하지만 집계 함수 없이 GROUP BY만 사용하는 건 거의 의미 없음.
✅ 2. 집계 함수와 함께 사용
SELECT name, COUNT(name), SUM(quantity) FROM sample51 GROUP BY name;
- 위 쿼리는 name을 기준으로 그룹화한 후,
- 각 그룹의 행 수(COUNT)
- quantity의 합계(SUM)를 구함
✅ 3. HAVING 구로 조건 지정
- 집계 함수는 WHERE 절에서 사용 불가 → WHERE는 GROUP BY보다 먼저 처리되므로 에러 발생
- 조건을 걸려면 HAVING 사용
SELECT name, COUNT(name) FROM sample51 GROUP BY name HAVING COUNT(name) = 1;
- HAVING은 그룹화된 결과에서 조건에 맞는 그룹만 필터링할 수 있음
✅ 4. GROUP BY에 지정하지 않은 열은 SELECT에서 집계함수 없이 사용 불가
-- 오류 발생 예시
SELECT name, quantity FROM sample51 GROUP BY name;
- quantity는 GROUP BY 대상이 아니고 집계함수도 안 썼기 때문에 오류 발생
- 해결 방법: 집계함수 사용 또는 GROUP BY에 포함
SELECT name, SUM(quantity) FROM sample51 GROUP BY name;
✅ 5. 정렬은 ORDER BY로
- GROUP BY는 정렬되지 않음
- 정렬이 필요할 경우 반드시 ORDER BY 사용
- DESC는 내림차순, ASC는 오름차순(기본)
SELECT name, COUNT(name), SUM(quantity) FROM sample51 GROUP BY name ORDER BY SUM(quantity) DESC;
💡 실무 활용 예
- 점포별/상품별/월별로 매출, 수량, 건수 등을 집계할 때 자주 사용
- 예: "상품별 매출 합계를 구하고, 높은 순으로 정렬"
23강 서브쿼리
✅ 서브쿼리 핵심 정리
1. 서브쿼리란?
- 다른 SQL 문장 안에 들어있는 SELECT문.
- 괄호 ()로 감싸서 사용.
- 보통 WHERE, FROM, SELECT, SET, INSERT 등에서 사용.
2. 주요 사용 예
▸ WHERE 절에서 사용
DELETE FROM sample54 WHERE a = (SELECT MIN(a) FROM sample54);
- a 컬럼의 최소값을 가진 행을 삭제.
- 스칼라 서브쿼리: 하나의 값만 반환.
▸ SELECT 절에서 사용
SELECT (SELECT COUNT(*) FROM sample51) AS cnt1, (SELECT COUNT(*) FROM sample54) AS cnt2;
▸ SET 절에서 사용
- a 값을 테이블 내 최대값으로 일괄 변경.
▸ FROM 절에서 사용 (인라인 뷰)
SELECT * FROM (SELECT * FROM sample54) AS sq;
▸ INSERT에서 사용
3. 주의사항
- MySQL에서는 동일 테이블을 DELETE나 UPDATE할 때, 서브쿼리에 포함시키면 오류 발생할 수 있음. → 인라인 뷰로 우회 가능
- Oracle에서는 FROM DUAL 사용 필요
- =, <, > 등 비교 연산자에는 반드시 스칼라 서브쿼리만 사용 가능
24강 상관 서브쿼리
EXISTS (SELECT명령)
- EXIXSTS 술어를 사용하면 서브쿼리가 반환하는 결괏값이 있는지 조사할 수 있음.
- 특히 EXIXSTS를 사용하는 경우에는 서브쿼리가 반드시 스칼라 값을 반환할 필요는 없음.
1. EXIXSTS
- 서브쿼리를 사용해 검색할 때 '데이터가 존재하는지 아닌지' 판별하기 위해 조건을 지정할 수도 있음.
> 이런 경우 EXIXSTS 술어를 사용해 조사
- WHERE 구에 조건을 지정해 ‘있음’으로 갱신하는 경우와 ‘없음’ 으로 갱신하는 경우로 나누어 처리.
2, NOT EXISTS
3. 상관 서브쿼리
UPDATE sample551 SET a = '있음' WHERE
EXISTS (SELECT * FROM sample 552 WHERE no2 = no);
- 부모 명령과 자식인 서브쿼리가 특저 관계를 맺는 것을 '상관 서브쿼리'라 부름.
4. IN
- 스칼라 값끼리 비교할 때는 = 연산자를 사용 (다만 집합을 비교할 때는 사용할 수 없음)
- IN을 사용하면 집합 안의 값이 존재하는지를 조사할 수 있음.
열명 IN ( 집합)
- IN의 왼쪽에는 하나의 열이 지정되어 있기 때문.
> IN은 집합 안에 값이 포함되어 있으면 참이 됨.
>반면 NOT IN으로 지정하면 집합에 값이 포함되어 있지 않을 경우 참이 됨.
- IN과 NULL
; NULL을 비교할 때는 IS NULL을 사용해야 함.
; NOT IN의 경우, 집합 안에 NULL 값이 있으면 (왼쪽 값이 집합 안에 포함되어 있지 않아도) 참을 반환하지 않음.
> 결과는 '불명(UNKOWN)'이 됨.