GROUP BY 사용 규칙
GROUP BY 사용 규칙
•
GROUP BY에 사용한 컬럼만 SELECT 절에 그대로 (집계함수 없이) 사용할 수 있다.
•
GROUP BY에 사용하지 않은 컬럼은 반드시 집계함수와 함께 사용해야 한다.
반드시 외우고, GROUP BY를 사용할 때는 위 내용을 항상 떠올리기 바란다.
MySQL은 버젼이나 SQL_MODE에 따라 GROUP BY에 사용하지 않은 컬럼을 집계함수 없이 사용 가능한 경우가 있다. 이러한 처리는 데이터 정확성에 문제가 발생할 수 있으므로 주의해야 한다.
-- [SQL-5-3-1]
-- GROUP BY를 잘 못 사용한 SQL
-- GROUP BY에는 ShopId만 정의함
-- OrdAmt를 SELECT절에서 집계함수 없이 사용
-- 하지만 MySQL은 SQL_MODE 설정에 따라 아래와 같은 SQL의 실행을 허용한다.
-- 대부분의 다른 DBMS는 허용하지 않는다.
SELECT T1.ShopId
,T1.OrdAmt -- > GROUP BY에 없는 컬럼이므로 사용할 수 없다.
FROM startdb.Ord T1
WHERE T1.OrdDtm >= STR_TO_DATE('20220101','%Y%m%d')
AND T1.OrdDtm < STR_TO_DATE('20220103','%Y%m%d')
AND T1.ShopId IN ('S012','S212')
GROUP BY T1.ShopId;
SQL
복사
위 SQL에서 OrdAmt는 반드시 아래와 같이 SUM과 같은 집계함수로 처리해야 한다.
-- [SQL-5-3-2]
SELECT T1.ShopId
,SUM(T1.OrdAmt) OrdAmt -- > GROUP BY에 없는 컬럼은 반드시 집계함수 처리
FROM startdb.Ord T1
WHERE T1.OrdDtm >= STR_TO_DATE('20220101','%Y%m%d')
AND T1.OrdDtm < STR_TO_DATE('20220103','%Y%m%d')
AND T1.ShopId IN ('S012','S212')
GROUP BY T1.ShopId;
ShopId OrdAmt
------ ---------
S012 16500.000
S212 8500.000
SQL
복사
Tip. MySQL의 SQL_MODE
MySQL의 SQL_MODE에 ONLY_FULL_GROUP_BY를 추가하면 GROUP BY를 제외한 항목을 집계함수 없이 SELECT 절에 사용하는 실수를 막을 수 있다.
-- 참고만 하고, 필요한 경우만 변경합니다.
SELECT @@SQL_MODE;
-- ONLY_FULL_GROUP_BY추가:
SET SESSION SQL_MODE = CONCAT('ONLY_FULL_GROUP_BY,',@@SQL_MODE);
-- 원상복구:
SET SESSION SQL_MODE = REPLACE(@@SQL_MODE,'ONLY_FULL_GROUP_BY,','');
SQL
복사
BOOSTER QUIZ
BOOSTER QUIZ ERD
BOOSTER QUIZ 5-3-1
아래 SQL에서 잘 못 처리된 부분을 고르고, 왜 잘못되었는지 설명하시오.
SELECT T1.HotColdCd -- 1
,T1.LaunchDt -- 2
FROM startdb.Item T1
WHERE T1.ItemCat = 'BEV' -- 3
GROUP BY T1.HotColdCd -- 4
SQL
복사
BOOSTER QUIZ 5-3-2
아래 SQL에서 GROUP BY에 필요한 컬럼을 적으시오.
SELECT MIN(T1.OrdDtm) FirstOrdDtm
,MAX(T1.OrdDtm) LastOrdDtm
,T1.MemberId
FROM startdb.Ord T1
WHERE T1.OrdDtm >= STR_TO_DATE('20220101','%Y%m%d')
AND T1.OrdDtm < STR_TO_DATE('20220103','%Y%m%d')
AND T1.ShopId IN ('S012','S212')
GROUP BY ?;
SQL
복사