Oracle 기준.
Case 변환
아스키코드 변환
ASCII('A') -- 65
CHR(65) -- 'A'
문자열 붙이기.
'문자열1'||'문자열2' 과 동일.
CONCAT('Hello', ' World') -- 'Hello World'
문자열 추출
[, 추출할_개수]를 생략할 경우 문자열 끝까지 추출
SUBSTR('Hello World', 7, 2) -- 'or'
Length('문자열')
LTRIM('xxxHello Worldxxx', 'x') -- ''Hello Worldxxx'
LTRIM('xxxHello Worldxxx', 'x') -- 'xxxHello World'
Default : both
TRIM('x' FROM 'xxxHello Worldxxx') -- 'Hello World'
ABS(숫자)
양수/음수/0 구별
SIGN(-99) -- -1 SIGN(0) -- 0 SIGN(77) -- 1
올림(숫자보다 크거나 같은 최소 정수 반환)
CEIL(38.123) -- 39 CEIL(-38.123) -- -38
버림(숫자보다 작거나 같은 최소 정수 반환)
FLOOR(38.123) -- 38 FLOOR(-38.123) -- -39
m자리 올림
ROUND(77.77777, 3) -- 77.778
m자리 뒤 버림 (m 생략시 Default : 0)
ROUND(77.77777, 3) -- 77.777
삼각함수
SELECT ENAME, SYSDATE+1, HIREDATE, EXTRACT(YEAR from HIREDATE), TO_NUMBER(TO_CHAR(HIREDATE, 'MMDD')) FROM EMP;
SELECT TO_CHAR(855726.872/1101.32159, 'L999,999,999.999') --L은 Local 화폐 FROM DUAL; -- ₩777.000
--※ 모든 반환값의 Type은 일치되어야 한다! --SIMPLE CASE EXPRESSION 조건 : (CASE 뒤 기준 표현이) EQUI조건인 경우 SELECT CASE 칼럼|조건식 WHEN 결과값 THEN 반환값(칼럼명|칼럼값) ... [ELSE 반환값(칼럼명|칼럼값)] -- 생략시 NULL END[ [AS] 별칭] FROM 테이블명 --SEARCHED CASE EXPRESSION 조건 : EQUI조건이 아닌 경우 (좀 더 다양한 조건을 가질 경우) SELECT CASE WHEN 조건식 THEN 반환값(칼럼명|칼럼값) ... [ELSE 반환값(칼럼명|칼럼값)] -- 생략시 NULL END[ [AS] 별칭] FROM 테이블명
SELECT ENAME, HIREDATE, CASE EXTRACT(YEAR FROM HIREDATE) WHEN 1981 THEN 'Since 1980' ELSE 'ETC' END HIREYEAR, SAL, CASE WHEN SAL>=2000 THEN 1000 ELSE (CASE WHEN SAL>=1000 THEN 500 ELSE 0 END) END BONUS FROM EMP;
Oracle 전용. CASE 표현이 EQUI 조건일 때, 짧게 표현할 수 있으므로 유용.
DECODE(표현식|칼럼, 기준값1, 반환값1[, 기준값2, 반환값2, ... , Default값])
-- Default값 : CASE표현의 ELSE 뒤 반환값
부서별로 월별 입사자의 평균 급여 조회
SELECT DEPTNO, AVG(CASE HIREMONTH WHEN 1 THEN SAL END) M01, AVG(CASE HIREMONTH WHEN 2 THEN SAL END) M02, AVG(CASE HIREMONTH WHEN 3 THEN SAL END) M03, AVG(CASE HIREMONTH WHEN 4 THEN SAL END) M04, AVG(CASE HIREMONTH WHEN 5 THEN SAL END) M05, AVG(CASE HIREMONTH WHEN 6 THEN SAL END) M06, AVG(DECODE(HIREMONTH, 7, SAL)) M07, AVG(DECODE(HIREMONTH, 8, SAL)) M08, AVG(DECODE(HIREMONTH, 9, SAL)) M09, AVG(DECODE(HIREMONTH, 10, SAL)) M10, AVG(DECODE(HIREMONTH, 11, SAL)) M11, AVG(DECODE(HIREMONTH, 12, SAL)) M12 FROM (SELECT ENAME, DEPTNO, EXTRACT(MONTH FROM HIREDATE) HIREMONTH, SAL FROM EMP) GROUP BY DEPTNO;
SELECT NVL(NULL 판단 대상, NULL일 때 대체값) FROM 테이블명;
SELECT NULLIF(EXPR1, EXPR2) FROM 테이블명;
SELECT COALESCE(EXPR1, EXPR2, ...) FROM 테이블명;
여러 행들의 그룹이 모여서 그룹당 단 하나의 결과를 돌려주는 함수
문법 | 설명 |
---|---|
COUNT(*|표현식) | NULL 제외 계산 문자,날짜 Type에도 사용 가능 |
MAX([DISTINCT|ALL] 표현식) MIN([DISTINCT|ALL] 표현식) | 문자,날짜 Type에도 사용 가능 |
SUM([DISTINCT|ALL] 표현식) | NULL 제외 계산 |
AVG([DISTINCT|ALL] 표현식) | |
STDDEV([DISTINCT|ALL] 표현식) | 표준편차 |
VARIAN([DISTINCT|ALL] 표현식) | 분산 |
팀별 각 포지션(FW, MF, DF, GK)의 인원수와 팀별 전체 인원수, 평균키 출력
SELECT TEAM_ID, NVL(SUM(DECODE(POSITION, 'FW', 1)), 0) FW, NVL(SUM(DECODE(POSITION, 'MF', 1)), 0) MF, NVL(SUM(DECODE(POSITION, 'DF', 1)), 0) DF, NVL(SUM(DECODE(POSITION, 'GK', 1)), 0) GK, COUNT(*) SUM, ROUND(AVG(HEIGHT), 2) AVG_HEIGHT FROM PLAYER GROUP BY TEAM_ID;
(집계 함수 제외하고,) 소그룹 간의 소계(전체가 아닌 어느 한 부분만을 셈한 합계) 계산
SELECT DNAME, JOB, COUNT(*) "TOTAL EMP", SUM(SAL) "TOTAL SAL" FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO GROUP BY ROLLUP(DNAME, JOB) --DNAME, JOB에 대한 "소"그룹 집"계" 출력 ORDER BY DNAME, JOB;
SELECT DNAME, JOB, COUNT(*) "TOTAL EMP", SUM(SAL) "TOTAL SAL" FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO GROUP BY CUBE(DNAME, JOB) ORDER BY DNAME, JOB;
SELECT DNAME, GROUPING(DNAME), JOB, GROUPING(JOB), COUNT(*) "TOTAL EMP", SUM(SAL) "TOTAL SAL" FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO GROUP BY ROLLUP(DNAME, JOB);
특정 항목에 대한 소계 계산
SELECT 'ALL DEPTS' DNAME, JOB, COUNT(*) "TOTAL EMP", SUM(SAL) "TOTAL SAL" FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO GROUP BY JOB UNION ALL SELECT DNAME, 'ALL JOBS' JOB, COUNT(*) "TOTAL EMP", SUM(SAL) "TOTAL SAL" FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO GROUP BY DNAME;
SELECT DECODE(GROUPING(DNAME), 1, 'ALL DEPTS', DNAME) DNAME, DECODE(GROUPING(JOB), 1, 'ALL JOBS', JOB) JOB, COUNT(*) "TOTAL EMP", SUM(SAL) "TOTAL SAL" FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO GROUP BY GROUPING SETS(JOB, DNAME); --칼럼간의 평등관계로 순서가 바뀌어도 결과는 같다.
SELECT WINDOW_FUNCTION (ARGUMENTS) OVER ([PARTITION BY 칼럼] [ORDER BY 절] [WINDOWING 절]) FROM 테이블명;
특정 칼럼에 대한 순위를 구하는 함수 (단, 동일 순위가 있으면 그 수만큼 순위가 넘어가버림)
SELECT JOB, ENAME, SAL, RANK() OVER (ORDER BY SAL DESC) ALL_RANK, --전체 급여 순위 RANK() OVER (PARTITION BY JOB ORDER BY SAL DESC) JOB_RANK --직업별 급여 순위 FROM EMP;
RANK 함수와 흡사하나, 동일한 순위를 하나의 건수로 취급.
SELECT JOB, ENAME, SAL, RANK() OVER (ORDER BY SAL DESC) RANK, DENSE_RANK() OVER (ORDER BY SAL DESC) DENSE_RANK FROM EMP;
동일값이라도 고유한 순위 부여. 동일 등수를 인정하지 않음.
SELECT JOB, ENAME, SAL, RANK() OVER (ORDER BY SAL DESC) RANK, ROW_NUMBER() OVER (ORDER BY SAL DESC) DENSE_RANK --SAL 기준에 따른 줄번호순 FROM EMP;
SELECT MGR, ENAME, SAL, SUM(SAL) OVER (PARTITION BY MGR) MGR_SUM --MGR별 급여 합계 FROM EMP;
SELECT MGR, ENAME, SAL, MAX(SAL) OVER (PARTITION BY MGR) MGR_MAX --MGR별 급여 최대값 FROM EMP;
SELECT MGR, ENAME, SAL, MIN(SAL) OVER (PARTITION BY MGR ORDER BY HIREDATE) MGR_MIN --MGR별 급여 최소값, 입사일 기준 정렬 FROM EMP;
SELECT MGR, ENAME, SAL, ROUND(AVG(SAL) OVER (PARTITION BY MGR), 2) MGR_AVG --MGR별 급여 평균 FROM EMP;
SELECT ENAME, SAL, COUNT(*) OVER (ORDER BY SAL RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING) SIM_CNT FROM EMP; --RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING : 현재 행의 급여값을 기준으로 급여가 -50 ~ +150 범위 내에 포함된 모든 행이 대상
모두 SQL Server에서 미지원.
SELECT DEPTNO, ENAME, SAL, FIRST_VALUE(ENAME) OVER (PARTITION BY DEPTNO ORDER BY SAL DESC ROWS UNBOUNDED PRECEDING) AS DEPT_RICH FROM EMP; --ROWS UNBOUNDED PRECEDING : 현재 행 지준으로 "파티션 내 첫 번째 행까지" 범위 지정
NTILE 이외 함수들은 SQL Server에서 미지원.
파티션 내 전체 칼럼 합계값에 대한 백분율 반환.
파티션별 윈도우에서 제일 먼저 나오는 행값을 0, 가장 늦게 나오는 행값을 1로 하여 행 순서별 백분율 반환. (상위 몇퍼센트에 있는가?)
같은 부서 소속 사원들의 집합에서 본인의 급여가 순서상 몇 번째 위치쯤에 있는 지 0과 1사이의 값으로 조회.
SELECT DEPTNO, ENAME, SAL, PERCENT_RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) PER_RANK FROM EMP;
파티션별 윈도우의 전체건수에서 현재 행보다 작거나 같은 건수에 대한 누적백분율 반환.
파티션별 전체 건수를 n등분한 Argument값 반환 (조 짜기)
테이블이나 집합에서 원하는 만큼의 행만 가져오고 싶을 때 사용하는 가상 칼럼(Pseudo Column)
SQL Server에서는
-- (SELECT 절에서)
TOP(n) WITH TIES
-- WITH TIES : 동일 수치 데이터 추가
SELECT문 WHERE ROWNUM 비교연산자 수치 -- 예시 : 3행까지 가져올 때 SELECT * FROM MYTABLE WHERE ROWNUM <= 3;
UPDATE 테이블명 SET 칼럼명 = ROWNUM;