(사용형식)
SELECT 컬럼list
FROM 테이블명
[WHERE 조건]
[GROUP BY 컬럼[,컬럼,..]]
[HAVING 조건]
[ORDER BY 컬럼|컬럼인덱스 [ASC|DESC],...];
- ORDER BY 절에 기술하는 컬럼은 SELECT절에 사용된 컬럼
또는 해당 테이블에서 그룹으로 나누기 위해 필요한 컬럼
- 집계함수가 사용되면 다중행결과 반환
- HAVING 조건 : 집계함수에 조건이 부여된 경우 기술
SELECT COUNT(*) FROM HR.EMPLOYEES
SELECT DEPARTMENT_ID,
COUNT(*)
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
ORDER BY 1;
SELECT DEPARTMENT_ID,
COUNT(*)
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
HAVING COUNT(*)>10
ORDER BY 1;
HAVING 말고 WHERE 쓰면 오류!
(사용형식)
SUM(expr)
SELECT DEPARTMENT_ID AS 부서,
SUM(SALARY) AS "급여 합계"
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
ORDER BY 1;
SELECT BUY_PROD AS 상품코드,
SUM(BUY_QTY) AS "매입수량 합계",
SUM(BUY_QTY*BUY_COST) AS "매입금액 합계"
FROM BUYPROD
WHERE BUY_DATE BETWEEN TO_DATE('20050201') AND LAST_DAY('20050201')
GROUP BY BUY_PROD
ORDER BY 1;
SELECT EXTRACT(MONTH FROM BUY_DATE) AS 월,
BUY_PROD AS 상품코드,
SUM(BUY_QTY) AS "매입수량 합계",
SUM(BUY_QTY*BUY_COST) AS "매입금액 합계"
FROM BUYPROD
WHERE EXTRACT(YEAR FROM BUY_DATE) = 2005
GROUP BY EXTRACT(MONTH FROM BUY_DATE), BUY_PROD
ORDER BY 1;
SELECT CASE WHEN SUBSTR(MEM_REGNO2,1,1)='1' OR
SUBSTR(MEM_REGNO2,1,1)='3' THEN '남성' ELSE '여성' END AS 구분,
SUM(MEM_MILEAGE) AS "마일리지 합계"
FROM MEMBER
GROUP BY CASE WHEN SUBSTR(MEM_REGNO2,1,1)='1' OR
SUBSTR(MEM_REGNO2,1,1)='3' THEN '남성' ELSE '여성' END
SELECT CART_MEMBER AS 회원,
SUM(CART_QTY) AS 구매수량합계
FROM CART
WHERE SUBSTR(CART_NO,1,6)='200504'
GROUP BY CART_MEMBER
서브쿼리 사용!
SELECT A.CART_MEMBER AS 회원번호,
A.SAMT AS 구매수량합계
FROM (SELECT CART_MEMBER,
SUM(CART_QTY) AS SAMT
FROM CART
WHERE CART_NO LIKE '200504%'
GROUP BY CART_MEMBER
ORDER BY 2 DESC) A
WHERE ROWNUM<=5;
SELECT BUY_PROD AS 상품코드,
SUM(BUY_QTY*BUY_COST) AS 매입금액합계
FROM BUYPROD
WHERE BUY_DATE BETWEEN TO_DATE('20050101') AND TO_DATE('20050331')
GROUP BY BUY_PROD
HAVING SUM(BUY_QTY*BUY_COST) >= 5000000
ORDER BY 1;
(사용형식)
RANK() OVER(ORDER BY 컬럼명 [ASC|DESC][,컬럼명 [ASC|DESC],...])
Alias는 사원번호, 사원명, 부서코드, 급여, 순위
SELECT EMPLOYEE_ID AS 사원번호,
EMP_NAME AS 사원명,
DEPARTMENT_ID AS 부서코드,
SALARY AS 급여,
RANK() OVER(ORDER BY SALARY DESC) AS 순위
FROM HR.EMPLOYEES;
빠른 사원부터 순위 부여
Alias는 사원번호, 사원명, 부서코드, 급여, 순위
SELECT EMPLOYEE_ID AS 사원번호,
EMP_NAME AS 사원명,
DEPARTMENT_ID AS 부서코드,
HIRE_DATE AS 입사일,
SALARY AS 급여,
RANK() OVER(ORDER BY SALARY DESC) AS 순위1,
RANK() OVER(ORDER BY SALARY DESC, HIRE_DATE ASC) AS 순위2
FROM HR.EMPLOYEES;
Alias는 상품번호, 상품명, 매입수량 ,순위
SELECT A.BUY_PROD AS 상품번호,
B.PROD_NAME AS 상품명,
SUM(BUY_QTY) AS 매입수량,
RANK() OVER(ORDER BY SUM(BUY_QTY) DESC) AS 순위
FROM BUYPROD A, PROD B
WHERE A.BUY_PROD = B.PROD_ID --조인조건
AND EXTRACT(YEAR FROM BUY_DATE) = 2005
GROUP BY A.BUY_PROD, B.PROD_NAME;
그룹별 순위 : PARTITION BY 절 사용 << 하나의 그룹에 여러개가 들어가있으면 안씀
(사용형식)
RANK() OVER (PARTITION BY 컬럼명[,컬럼명,...] ORDER BY 컬럼명 [ASC|DESC][,컬럼명 [ASC|DESC],...])
Alias는 사원번호, 사원명, 부서코드, 급여, 순위
SELECT EMPLOYEE_ID AS 사원번호,
EMP_NAME AS 사원명,
DEPARTMENT_ID AS 부서코드,
SALARY AS 급여,
RANK() OVER(PARTITION BY DEPARTMENT_ID ORDER BY SALARY DESC) AS 순위
FROM HR.EMPLOYEES;
(사용형식)
MIN(컬럼명)|MAX(컬럼명) KEEP(DENSE_RANK FIRST|LAST ORDER BY 컬럼명 [ASC|DESC])
OVER(PARTITION BY 컬럼명)
최대급여와 최소급여를 조회하시오.
Alias는 사원번호, 사원명, 부서코드, 급여, 최소급여, 최대급여
SELECT EMPLOYEE_ID AS 사원번호,
EMP_NAME AS 사원명,
DEPARTMENT_ID AS 부서코드,
SALARY AS 급여,
MIN(SALARY) KEEP(DENSE_RANK FIRST ORDER BY SALARY) OVER(PARTITION BY DEPARTMENT_ID) AS 부서최소급여,
MAX(SALARY) KEEP(DENSE_RANK LAST ORDER BY SALARY) OVER(PARTITION BY DEPARTMENT_ID) AS 부서최대급여
FROM HR.EMPLOYEES
ORDER BY 3, 4;
(사용형식)
AVG(expr)
SELECT PROD_LGU AS 분류코드,
AVG(PROD_COST) AS "평균 매입가"
FROM PROD
GROUP BY PROD_LGU
ORDER BY 1;
소수점은 자르거나 반올림
ROUND( AVG(PROD_COST)) AS "평균 매입가"
SELECT DEPARTMENT_ID AS 부서코드,
AVG(EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE)) AS "평균 근속년수"
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
ORDER BY 1;
소수 첫째자리에서 반올림
ROUND(AVG(EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE)),1) AS "평균 근속년수"
SELECT DEPARTMENT_ID AS 부서,
ROUND(AVG(SALARY)) AS 평균급여
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
ORDER BY 1;
SELECT TRUNC(EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM MEM_BIR),-1)||'대' AS 연령대,
ROUND(AVG(MEM_MILEAGE)) AS "평균 마일리지"
FROM MEMBER
GROUP BY TRUNC(EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM MEM_BIR),-1)
ORDER BY 1;
COUNT(컬럼명|*)
- '컬럼명|*' : 외부조인(OUTER JOIN)을 제외하고 '컬럼명'이나 '*'는 차이가 없음
- 외부조인인 경우 '*'을 사용하면 자료가 없어도 '1'을 출력함(NULL값을 갖는 행이 존재하기 때문)
따라서 외부조인에서 COUNT함수 사용시 '컬럼명'을 기본키 컬럼으로 기술하는것이 안전하다
SELECT DEPARTMENT_ID AS 부서코드,
COUNT(*) AS 인원수1,
COUNT(EMP_NAME) AS 인원수2,
COUNT(DEPARTMENT_ID) AS 인원수3
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
ORDER BY 1;
인원수 3만 다르게 나옴
한명만 부서코드가 NULL이기 때문에 갯수가 다르게 나오는것...
킴벌리만 NULL
마찬가지로COMMISSION_PCT도 NULL값이 많기때문에 이걸 기준으로 하면 더 엉망으로 나옴
SELECT DISTINCT DEPARTMENT_ID
FROM HR.EMPLOYEES
ORDER BY 1;
SELECT DISTINCT DEPARTMENT_ID
FROM HR.DEPARTMENTS
ORDER BY 1;
부서테이블에서 DEPARTMENT_ID는 기본키이기때문에 중복되거나 NULL값을 가질수가 없다
사원테이블에서는 외래키이기 때문에 NULL이 가능했던것!
SELECT DISTINCT DEPARTMENT_ID AS 부서코드,
COUNT (*) AS 인원수1,
COUNT (A.EMP_NAME) AS 인원수2
FROM HR.EMPLOYEES A, HR.DEPARTMENTS B
WHERE A.DEPARTMENT_ID(+)=B.DEPARTMENT_ID
GROUP BY B.DEPARTMENT_ID
ORDER BY 1;
대상이 되어지는 테이블의 기본키를 써주ㅓ...외부조인...
근데 왜 안돌아가
SELECT DEPARTMENT_ID AS 부서코드,
COUNT(*) AS 인원수
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID
HAVING COUNT(*)>=5
ORDER BY 1;
그룹함수에 조건이 부여될때는 HAVING절을 사용한다
SELECT PROD_LGU AS 분류코드,
COUNT(*) AS 상품수
FROM PROD
GROUP BY PROD_LGU
ORDER BY 1;
SELECT EXTRACT(MONTH FROM BUY_DATE) AS 월,
COUNT(BUY_QTY) AS 매입건수
FROM BUYPROD
GROUP BY EXTRACT(MONTH FROM BUY_DATE)
ORDER BY 1;
SELECT SUBSTR(CART_NO,5,2) AS 월,
COUNT(CART_QTY) AS 매출건수
FROM CART
WHERE CART_NO LIKE '2005%'
GROUP BY SUBSTR(CART_NO,5,2)
HAVING COUNT(CART_QTY)>=10
ORDER BY 1;
SUBSTR(CART_NO,5,2) : 5번째 글자부터 2글자를 꺼내
🚨 이게 틀린이유: 같은날 한사람이 여러건 샀어도 1건으로 취급하고싶은건데 여러건으로 취급되었기 때문 >> DISTINCT로 중복 해결하자SELECT SUBSTR(A.CNO,5,2)||'월' AS 월,
COUNT(*) AS 매출건수
FROM (SELECT DISTINCT CART_NO AS CNO
FROM CART) A
WHERE SUBSTR(A.CNO,1,4) = '2005'
GROUP BY SUBSTR(A.CNO,5,2)
HAVING COUNT(*)>=10
ORDER BY 1;
(사용형식)
MAX(expr) / MIN(expr)
🚨 집계함수는 중복으로 사용 안되므로 주의해가면서 풀어보기!
SELECT DEPARTMENT_ID AS 부서코드,
EMP_NAME AS 사원명,
MAX(SALARY) AS 최대급여,
MAX(SALARY) AS 최소급여
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID, EMP_NAME
ORDER 1;
왜 또 안돌아가
혀튼 이건 우리가 찾는 형태의 테이블은 아님 . 다르게 짜야함 부서별로 나눠서 이름 쓰고 자기들끼리 급여가 높은지 낮은지 써있음...
SELECT B.EMPLOYEE_ID AS 사원번호,
B.EMP_NAME AS 사원명,
A.DEPARTMENT_ID AS 부서코드,
A.MSAL AS 급여
FROM (SELECT DEPARTMENT_ID,
MAX(SALARY) AS MSAL
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID) A,
HR.EMPLOYEES B
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID
AND B.SALARY = A.MSAL
ORDER BY 3;
SELECT B.EMPLOYEE_ID AS 사원번호,
B.EMP_NAME AS 사원명,
A.DEPARTMENT_ID AS 부서코드,
A.MSAL AS 급여
FROM (SELECT DEPARTMENT_ID,
MAX(SALARY) AS MSAL
FROM HR.EMPLOYEES
GROUP BY DEPARTMENT_ID) A,
HR.EMPLOYEES B
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID
AND B.SALARY = A.MSAL
ORDER BY 3;
SELECT A.CART_MEMBER,
SUM(A.CART_QTY*B.PROD_PRICE) AS ASUM
FROM CART A, PROD B
WHERE A.CART_PROD = B.PROD_ID
AND CART_NO LIKE '200505%'
GROUP BY A.CART_MEMBER
SELECT F.MEM_ID AS 회원번호,
F.MEM_NAME AS 회원명,
D.MCASUM AS 구매금액
FROM (SELECT MAX(C.ASUM) AS MCASUM
FROM(SELECT A.CART_MEMBER AS ACID,
SUM(A.CART_QTY*B.PROD_PRICE) AS ASUM
FROM CART A, PROD B
WHERE A.CART_PROD = B.PROD_ID
AND CART_NO LIKE '200505%'
GROUP BY A.CART_MEMBER) C) D,
(SELECT A.CART_MEMBER AS ACID,
SUM(A.CART_QTY*B.PROD_PRICE) ASUM
FROM CART A, PROD B
WHERE A.CART_PROD = B.PROD_ID
AND CART_NO LIKE '200505%'
GROUP BY A.CART_MEMBER) E,
MEMBER F
WHERE D.MCASUM = E.ASUM
AND F.MEM_ID = E.ACID;