반응형
Web Development · MySQL
MySQL MIN · MAX —
최솟값·최댓값 완전 정리
MIN / MAX 기본 · GROUP BY와 조합 · 서브쿼리로 해당 행 찾기
시작 오늘 분석할 코드
-- 전체 usertbl에서 최대·최소 키 SELECT name, MAX(height), MIN(height) FROM usertbl; -- 회원별 최대·최소 키 (GROUP BY 포함) SELECT name, MAX(height), MIN(height) FROM usertbl GROUP BY name; -- 최대 or 최소 키를 가진 회원 행 전체 조회 SELECT name, height FROM usertbl WHERE height = (SELECT MAX(height) FROM usertbl) OR height = (SELECT MIN(height) FROM usertbl);
MAX/MIN은 집계함수로, 그룹 내 가장 큰/작은 값을 반환한다. GROUP BY 없이 쓰면 전체 테이블, GROUP BY와 함께 쓰면 각 그룹의 최댓값/최솟값을 구한다.
1 MAX · MIN 기본 개념
MAX(컬럼)
그룹 내 최댓값. 숫자, 날짜, 문자열(사전순 마지막) 모두 적용 가능
MIN(컬럼)
그룹 내 최솟값. NULL은 무시됨 (NULL이 가장 작다고 취급 안 함)
GROUP BY 없을 때
전체 테이블을 하나의 그룹으로 보고 전체 최댓값/최솟값 반환
GROUP BY 있을 때
그룹별 최댓값/최솟값 반환 — 이름별, 지역별 등으로 분류 가능
-- GROUP BY 없음 → 전체 테이블의 최대·최소 height = 1행 반환 SELECT MAX(height), MIN(height) FROM usertbl; -- 결과: MAX=183, MIN=170 (1행) -- GROUP BY name → 이름별 최대·최소 (usertbl은 1인당 1행이라 MAX=MIN=자기 키) SELECT name, MAX(height), MIN(height) FROM usertbl GROUP BY name; -- usertbl에 동명이인 없으면 MAX = MIN = 각자 키
첫 번째 쿼리
SELECT name, MAX(height) FROM usertbl는 name과 MAX(height)가 결합 불가능한 쿼리다. name은 GROUP BY 없이 집계함수와 섞으면 어떤 name이 출력될지 불확정이다. GROUP BY name을 추가하거나 서브쿼리로 해당 행을 찾아야 한다.2 서브쿼리로 MAX/MIN 해당 행 찾기
MAX(height)는 값(예: 183)을 알려주지만 그 회원의 이름·주소 등 다른 컬럼은 알 수 없다. 서브쿼리를 이용해 해당 값을 가진 전체 행을 찾는다.
-- 키 최댓값과 최솟값을 각각 서브쿼리로 구하고, 그 값에 해당하는 행 조회 SELECT name, height FROM usertbl WHERE height = (SELECT MAX(height) FROM usertbl) OR height = (SELECT MIN(height) FROM usertbl); -- 결과: 키 183인 회원 + 키 170인 회원 (name, height 출력) -- 최고 구매액 회원 구매 내역 SELECT * FROM buytbl WHERE price = (SELECT MAX(price) FROM buytbl); -- 결과: 단가가 가장 비싼 상품을 구매한 행
패턴 정리: MAX/MIN만으로는 "값"만 알 수 있다. 해당 행 전체가 필요하면
WHERE 컬럼 = (SELECT MAX(컬럼) FROM 테이블) 서브쿼리 패턴을 쓴다.3 MAX · MIN 활용 패턴
-- 날짜 컬럼: 가장 최근 가입자 SELECT name, mDate FROM usertbl WHERE mDate = (SELECT MAX(mDate) FROM usertbl); -- 그룹별 최고가 상품 SELECT groupName, MAX(price) AS 최고단가, MIN(price) AS 최저단가 FROM buytbl GROUP BY groupName; -- 최솟값 제외하고 조회 (MIN보다 큰 것만) SELECT name, height FROM usertbl WHERE height > (SELECT MIN(height) FROM usertbl) ORDER BY height;
| 컬럼 타입 | MAX | MIN |
|---|---|---|
| INT / SMALLINT | 가장 큰 숫자 | 가장 작은 숫자 |
| DATE / DATETIME | 가장 최근 날짜 | 가장 오래된 날짜 |
| VARCHAR / CHAR | 사전순 마지막 | 사전순 처음 (ㄱ, A...) |
| NULL 포함 | NULL 무시 후 최대 | NULL 무시 후 최소 |
반응형
4 GREATEST · LEAST — 행 내 비교
MAX/MIN은 여러 행의 같은 컬럼을 비교하는 집계함수다. 반면 GREATEST와 LEAST는 한 행 안의 여러 컬럼을 비교한다.
-- MAX(height): 전체 행 중 height 최댓값 (집계함수) SELECT MAX(height) FROM usertbl; -- GREATEST(a, b, c): 한 행 안의 여러 값 중 최댓값 (행 내 비교) SELECT GREATEST(10, 20, 30); -- → 30 SELECT LEAST(10, 20, 30); -- → 10 -- 실용 예: 두 컬럼 중 큰 값을 기준으로 비교 SELECT name, GREATEST(price, amount) AS 더큰값 FROM buytbl;
| 구분 | MAX/MIN | GREATEST/LEAST |
|---|---|---|
| 비교 범위 | 여러 행의 같은 컬럼 | 한 행 안의 여러 컬럼/값 |
| 집계함수 여부 | 집계함수 (GROUP BY 관련) | 일반 함수 (행 단위) |
| WHERE 사용 | 불가 (HAVING 사용) | 가능 |
| 인자 개수 | 컬럼 1개 | 컬럼/값 여러 개 |
5 실습 시나리오 — usertbl + buytbl 활용
usertbl 10명, buytbl 12건 데이터를 대상으로 MAX/MIN 활용 패턴을 정리한다.
-- ① 전체 usertbl 키 최댓값·최솟값 SELECT MAX(height) AS 최대키, MIN(height) AS 최소키 FROM usertbl; -- → MAX=183, MIN=170 -- ② 가입일 범위 확인 SELECT MIN(mDate) AS 첫가입일, MAX(mDate) AS 최근가입일 FROM usertbl; -- ③ 가장 비싼 상품, 가장 저렴한 상품 SELECT MAX(price) AS 최고단가, MIN(price) AS 최저단가 FROM buytbl; -- ④ 그룹별 최고/최저 단가 SELECT groupName, MAX(price) AS 최고단가, MIN(price) AS 최저단가, MAX(price)-MIN(price) AS 가격차이 FROM buytbl GROUP BY groupName; -- ⑤ 키 최대/최소 회원 행 조회 (서브쿼리) SELECT name, height, addr FROM usertbl WHERE height = (SELECT MAX(height) FROM usertbl) OR height = (SELECT MIN(height) FROM usertbl);
패턴 응용:
MAX(price) - MIN(price)를 계산하면 그룹 내 가격 분산(범위)을 알 수 있다. 집계함수 결과끼리 사칙연산도 가능하다.6 집계함수 5종 비교
| 함수 | 역할 | NULL | 예시 |
|---|---|---|---|
MAX(col) |
최댓값 | 무시 | MAX(height) → 183 |
MIN(col) |
최솟값 | 무시 | MIN(height) → 170 |
SUM(col) |
합계 | 무시 | SUM(price*amount) → 총 구매액 |
AVG(col) |
평균 | 분모 제외 | AVG(height) → 평균 키 |
COUNT(*) |
행 수 | 포함 | COUNT(*) → 총 행 수 |
5 자주 하는 실수
| 실수 | 증상 | 해결 |
|---|---|---|
| SELECT name, MAX(height) — GROUP BY 없음 | 비결정적 name 반환 or 오류 | GROUP BY name 추가 또는 서브쿼리 사용 |
| WHERE MAX(height) > 값 | Invalid use of group function | WHERE는 HAVING으로 — HAVING MAX(height) > 값 |
| NULL 있는 컬럼 MIN/MAX | NULL이 결과에 나오지 않아 혼란 | NULL은 집계 시 무시 — IS NULL 조건 별도 처리 |
| MAX만 쓰고 그 행 정보 못 찾음 | 이름·주소 등 다른 컬럼 없음 | WHERE col = (SELECT MAX(col) FROM tbl) 패턴 |
핵심 한 줄 요약
MAX(컬럼)그룹 내 최댓값 — 숫자/날짜/문자 모두 가능
MIN(컬럼)그룹 내 최솟값 — NULL은 무시
GROUP BY 없음전체 테이블 대상 — 결과 1행
GROUP BY 컬럼그룹별 MAX/MIN — 회원별, 지역별, 그룹별
WHERE 서브쿼리 패턴WHERE height = (SELECT MAX(height) FROM ...) — 해당 행 전체 조회
OR 연결WHERE height = MAX 서브쿼리 OR height = MIN 서브쿼리
날짜 MAXMAX(mDate) = 가장 최근 날짜 (큰 날짜가 최신)
날짜 MINMIN(mDate) = 가장 오래된 날짜 (작은 날짜가 오래됨)
문자열 MAX사전순으로 마지막 값 (Z, ㅎ 계열)
WHERE vs HAVINGMAX()가 있는 조건은 WHERE 불가 → HAVING 사용
MAX(price*amount)식 결과의 최댓값도 가능 — MAX 안에 연산식 사용
GROUP BY + MAX그룹별 최고가 — MAX(price)를 groupName별로
NULL 처리NULL은 MAX/MIN 집계에서 무시됨 — COALESCE로 대체 가능
GREATEST(a,b,c)한 행 안의 여러 값 중 최댓값 — 집계함수와 다름
LEAST(a,b,c)한 행 안의 여러 값 중 최솟값
MAX vs GREATESTMAX=여러 행 비교(집계), GREATEST=한 행 내 여러 값 비교
MIN mDate가장 오래된 가입자 날짜 — WHERE mDate = (SELECT MIN(mDate)...)
MAX 서브쿼리 ORWHERE col = (MAX 서브쿼리) OR col = (MIN 서브쿼리) — 양 극단 행
HAVING MAXHAVING MAX(height) >= 180 — MAX 조건은 HAVING에 걸기
MAX - MINMAX(price) - MIN(price) = 그룹 내 가격 범위 (분산 측정)
MAX + GROUP BY그룹별 최댓값 — SELECT groupName, MAX(price) GROUP BY groupName
MAX(식)MAX(price*amount) — 계산식 결과의 최댓값도 가능
집계 후 ORDER BYSELECT MAX(price) GROUP BY groupName ORDER BY MAX(price) DESC
MIN 제외 필터WHERE height > (SELECT MIN(height) ...) — 최솟값 초과 행만
모든 집계 무시 대상SUM/AVG/MAX/MIN 모두 NULL 무시 — 전체 NULL이면 결과도 NULL
2번째 최댓값WHERE col = (SELECT MAX(col) FROM t WHERE col < (SELECT MAX(col) FROM t))
GROUP BY MAX 정렬결과에서 가장 큰 그룹 찾기 → ORDER BY MAX(컬럼) DESC LIMIT 1
MIN(mDate) 의미날짜 최솟값 = 가장 오래된 날짜 = 첫 가입자/첫 구매일
MAX(mDate) 의미날짜 최댓값 = 가장 최근 날짜 = 최신 가입자/최근 구매일
집계함수 중첩 불가MAX(SUM(...)) 중첩 불가 — 서브쿼리나 FROM 절로 우회
WHERE OR 패턴WHERE col = (SELECT MAX...) OR col = (SELECT MIN...) — 양 극단 행
Tags
#MySQL #MIN #MAX #최솟값 #최댓값 #집계함수 #서브쿼리 #GROUP BY #SQL #데이터베이스 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
MySQL, MIN, MAX, 최솟값, 최댓값, 집계함수, 서브쿼리, GROUP BY, SQL, 데이터베이스, 웹개발, 티스토리
반응형
'php' 카테고리의 다른 글
| MySQL WITH ROLLUP — 소계·합계 자동 계산 완전 정리 (0) | 2026.07.14 |
|---|---|
| MySQL HAVING — GROUP BY 결과 필터링 완전 정리 (0) | 2026.07.14 |
| MySQL 테이블 복사 · CREATE TABLE SELECT 완전 정리 (0) | 2026.07.14 |
| MySQL 서브쿼리 · ANY · ALL · IN 완전 정리 (0) | 2026.07.14 |
| MySQL GROUP BY · 집계함수 · AS 완전 정리 (0) | 2026.07.14 |
왕진 블로그

댓글