SELECT [DISTINCT] 컬럼명 [ALIAS]
FROM 테이블명
[ WHERE 조건식][ GROUP BY 컬럼 또는 표현식]
[HAVING 그룹조건식][ ORDER BY 컬럼명];
WHERE 절은 FROM 절에 정의된 집합 (주로 테이블) 의 개별 행에 WHERE 절의 조건절이 먼저 적용되고, WHERE 절의 조건에 맞는 행이 GROUP BY 절의 대상이 된다. 그 다음 결과 집합의 행에 HAVING 조건절이 적용된다. 결과적으로 HAVING 절의 조건을 만족하는 내용만 출력된다. 즉, HAVING 절은 WHERE 절과 비슷하지만 그룹을 나타내는 결과 집합의 행에 조건이 적용된다는 점에서 차이가 있다.
GROUP BY 절과 HAVING 절의 순서를 바꾸어서 수행하더라도 문법 에러가 없고 결과물도 동일하게 출력한다. 그렇지만 SQL 내용을 보면, 그룹핑 되어 통계 정보가 만들어 지고, 이후 적용된 결과 값에 대한 HAVING 절의 제한 조건에 맞는 데이터만 출력하는 것으로 GROUP BY 절과 HAVING 절의 논리적 순서를 지키는 것을 권고한다.
GROUP BY 소그룹의 데이터 중 일부만 필요한 경우, GROUP BY 연산 전 WHERE 절에서 조건을 적용하여 필요한 데이터만 추출하여 GROUP BY 연산을 하는 방법과, GROUP BY 연산 후 HAVING 절에서 필요한 데이터만 필터링 하는 두 가지 방법을 사용할 수 있다. 그렇지만 가능하면 WHERE 절에서 조건절을 적용하여 GROUP BY 의 계산 대상을 줄이는 것이 효율적이다.
NULL 을 ZERO 로 표현하기 위해 NVL (Oracle) / ISNULL (SQL Server) 함수를 사용하는 경우가 많은데, 다중 행 함수를 사용하는 경우 불필요한 부하가 발생할 수 있다. 다중 행 함수는 입력 값으로 전체 건수가 NULL 값인 경우에만 함수의 결과가 NULL 이 나오고, 전체 건수 중 일부만 NULL 인 경우는 NULL 인 행을 다중 행 함수의 대상에서 제외한다.
예를 들면, 100명 중 10명의 성적이 NULL 값일 때, 평균을 구하는 다중 행 함수 AVG 를 사용하면 NULL 값이 아닌 90명의 성적에 대해서 평균값을 구하게 된다.
CASE 표현 사용 시 ELSE 절을 생략하게 되면 Default 값이 NULL 이다. 반면, SUM(CASE 컬럼 WHEN 값1 THEN 값2 ELSE 0 END) 처럼 ELSE 절에서 0을 지정하면 불필요한 0이 SUM 연산에 사용되므로 자원의 사용이 많아진다. 따라서 가능한 ELSE 절은 상수값을 사용하지 않거나, 작성하지 않는 것이 좋다. Oracle DECODE GKATNDML 4번째 인자 또한 Default 로 NULL 이 할당된다.
레포트 출력 시 NULL 이 아닌 0 을 표기하고 싶다면 SUM(NVL(i,0)) 보다는 NVL(SUM(i),0) 처럼 전체 SUM 의 결과에 대해 함수를 사용하도록 한다.
SELECT 컬럼명 [ALIAS] FROM 테이블명
[ WHERE 조건식][ GROUP BY 컬럼 또는 표현식]
[HAVING 그룹조건식] ORDER BY 컬럼 또는 표현식 [ASC / DESC]]
5 SELECT 컬럼명 [ALIAS]
1 FROM 테이블명
2 WHERE 조건식
3 GROUP BY 컬럼 또는 표현식
4 HAVING 그룹조건식
6 ORDER BY 컬럼 또는 표현식
-- 잘못된 사례
SELECT ENAME, SAL
FROM EMP
WHERE ROWNUM < 4
ORDER BY SAL DESC;
-- 올바른 사례
SELECT ENAME, SAL
FROM (SELECT ENAME, SAL FROM EMP ORDER BY SAL DESC)
WHERE ROWNUM < 4;
TOP(50) PERCENT [WITH TIES]