기본 select 문 : 3. select empno, ename, sal
1. from emp
2. where deptno = 20
4. order by hiredate desc ;
함수 :
문제121. (복습문제) 부서번호가 10번, 20번인 사원들의 이름과 월급과
부서번호를 출력하는데 월급이 높은 사원부터 출력하시오 !
select ename, sal, deptno
from emp
where deptno in ( 10, 20 )
order by sal desc;
문제122. (복습문제) 이름의 첫글자가 S 로 시작하는 사원들의 이름과
월급과 입사일을 출력하는데 월급을 출력할 때 다음과 같이
천단위를 부여해서 출력하시오 ! (책 P94)
예: 3,000
select ename, **to_char( sal, '999,999')** , hiredate
from emp
where ename like 'S%';
문제123. (복습문제) 이름, 보너스(sal * 2300) 을 출력하는데 한글로
이름과 보너스라고 컬럼명이 나오게 하고 보너스를 출력할때
천단위, 백만단위의 콤마가 출력되게 하시오 !
select ename as 이름,
to_char( sal * 2300, '$999,999,999') as 보너스
from emp ;
설명: 숫자 --> 문자로 변환하는 to_char 함수를 사용해야 단위표시를
할 수 있습니다. to_char( 컬럼명, 'data 포멧' )
테이블의 결측치 데이터를 오라클에서는 null 값이라 합니다.
null 값 ?
→ null이 알 수 없는 값이기 때문에 숫자 + null = null 이 나온다. 알 수 없는 값이 나온다.
데이터가 없는 상태
알 수 없는 값 (unknown)
문제124. 이름과 월급, 커미션, 월급 + 커미션을 출력하시오 !
select ename, sal, comm, sal + comm
from emp ;
설명: 커미션(comm) 이 null 이면 sal + comm 이 null 로 출력됩니다.
왜냐면 null 이 알 수 없는 값이기 때문입니다.
그래서 계산이 되게 하려면 null 값을 다른 값으로 치환해야 합니다.
select ename, sal, nvl( comm, 0 )
from emp;
문제125. 이름과 월급과 커미션, 월급 + 커미션을 출력하는데
월급 + 커미션에서 커미션이 null 이면 자기 월급이라도
출력되게하시오 !
select ename, sal, comm, sal + nvl( comm, 0 )
from emp;
설명: nvl(comm, 0) 을 쓰게 되면 실제로 데이터가 null 에 0 으로 변경
되는것은 아니고 이 출력되는 sql 에서만 변경이 되는것입니다.
문제126. nvl2 함수를 사용해서 이름, 월급, 커미션, 월급 + 커미션을
출력하시오 ! ( ocp 시험용 )
select ename, sal, comm, nvl2( comm, sal + comm, sal )
from emp;
설명: nvl2( comm, comm 이 null 아닐때 , comm 이 null 일 때 )
문제127. (복습문제) 커미션이 null 인 사원들의 이름과 월급과 커미션을 출력하는데 커미션이 null 인 사원들은 0 으로 출력하시오 !
select ename, sal, nvl( comm, 0 )
from emp
where comm is null ;
문제128. (ocp 시험 문제) 이름, 커미션을 출력하는데 커미션이 null
인 사원들은 no comm 이라는 글씨로 출력하시오 !
문제129. (ocp 시험문제) 이름, 관리자번호(mgr) 을 출력하는데
관리자번호가 null 인 사원들은 no manager 라는 글씨로
출력되게하시오 !
select ename, nvl( to_char( mgr ), 'no manager' )
from emp;
문제130.(복습문제) market_2022 에 시군구명 컬럼의 데이터를
출력하는데 중복을 제거해서 출력하시오 !
select distinct 시군구명
from market_2022;
문제131. (복습문제) market_2022 에서 상호명이 스타벅스 를 포함하고
있는 모든 행과 모든 컬럼을 출력하시오 !
select *
from market_2022
where 상호명 like '%스타벅스%';
문제132. (복습문제) 위의 결과를 다시 출력하는데 시군구명이 강남구인
것만 출력하시오 !
select *
from market_2022
where 상호명 like '%스타벅스%' and 시군구명='강남구';
문법: 이름, 부서번호, 보너스를 출력하는데
보너스가 부서번호가 10번이면 5000 을 출력하고
부서번호가 20번이면 3000 을 출력하고
나머지 부서번호는 0 을 출력하시오 !
**코드 없이 if 문을 구현하겠다.**
↑
select ename, deptno, **decode( deptno, 10, 5000, 20, 3000, 0 )** as 보너스
from emp;
설명: decode( 컬럼명, 찾을값1, 출력할 값1,
찾을값2, 출력할값2, 기본값)
문제133. (점심시간 문제) 이름, 직업, 보너스를 출력하는데
보너스가 직업이 SALESMAN은 9000 을 출력하고
직업이 ANALYST 면 7000 을 출력하고
직업이 MANAGER 면 6000 을 출력하고
나머지 직업은 0 을 출력하시오 !
힌트:
select ename, deptno, decode( deptno, 10, 5000, 20, 3000, 0 ) as 보너스
from emp;
문제134. 이름, 월급, 입사일, 입사한 년도(4자리) 를 출력하시오 !
select ename, sal, hiredate, to_char(hiredate, 'RRRR')
from emp;
※ 설명: to_char( 날짜컬럼, 날짜포멧 )
문제135. 이름, 월급, 입사한 년도 4자리, 보너스를 출력하는데
입사한 년도가 1981 년도면 보너스를 9000 으로 출력하고
나머지 년도는 그냥 0 으로 출력하시오 !
select ename, sal, to_char(hiredate, 'RRRR') as 년도,
decode( to_char(hiredate,'RRRR') , '1981', 9000, 0 ) as 보너스
from emp;
문제136. (복습문제) 사원 테이블에서 이름, 이름의 첫번째 철자만
출력하시오 !
힌트: substr 을 이용하세요 !
select ename, substr( ename, 1, 1 )
from emp;
문제137. 이름, 보너스를 출력하는데 보너스가 이름의 첫번째 철자가
S 이면 보너스를 5000을 출력하고 A 이면 3000 을 출력하고
나머지 사원들은 0 을 출력하시오 !
select ename, decode( substr( ename, 1, 1 ), 'S', 5000, 'A', 3000, 0 ) as 보너스
from emp;
★ decode 관련해서 우리나라 금융권에서 예전에 발생했던 이슈 !
문제138. 이름과 직업과 월급을 출력하는데 월급이 높은 사원부터
출력하시오 !
select ename, job, sal
from emp
order by sal desc;
문제139. 이름과 보너스를 출력하는데 보너스가 직업이 PRESIDENT 면
null 로 출력하고 나머지 사원들은 자기 자신의 월급이
보너스로 출력되게하시오 !
select ename, decode( job, 'PRESIDENT', null, sal ) as 보너스
from emp;
문제140. 위의 결과를 다시 출력하는데 보너스가 높은 사원부터
출력하시오 !
select ename, decode( job, 'PRESIDENT', null, sal ) as 보너스
from emp
order by 보너스 desc ;
※ decode( job, 'PRESIDENT', null, sal )
세번째 인자값의 데이터 유형에 의해서 네번째 인자값의 데이터 유형이
결정이 됩니다. null 은 문자형입니다. 그래서 sal 이 문자형으로 출력이
되었습니다.
문제141. (SQLP 시험) 위의 결과가 제대로 나오게 SQL 을 튜닝하시오 !
select ename, decode( job, 'PRESIDENT', to_number(null), sal ) as 보너스
from emp
order by 보너스 desc ;
※ decode 의 유명한 암시적 형변환 사례 ! 오라클 bug 인데
아직도 해결이 안되었습니다.
decode 는 이퀄(=) 비교만 가능합니다. 그런데 case 는 이퀄(=) 비교
뿐만 아니라 non equal 비교도 가능합니다.
문제142. 이름, 월급, 보너스를 출력하는데 월급이 3000 이상이면
보너스를 9000 을 출력하고 월급이 1000이상이고 3000 보다 작으면
보너스를 2000을 출력하고 나머지 사원들은 0 을 출력하시오 !
select ename, sal, case when sal >= 3000 then 9000
when sal >= 1000 then 2000
else 0 end as 보너스
from emp;
문제143. 이름, 부서번호, 보너스를 출력하는데 보너스가
부서번호가 10번이면 9000 을 출력하고
부서번호가 20번이면 6000 을 출력하고
나머지 부서번호는 0 을 출력하시오 ! (case 문)
답:
select ename, deptno , case when deptno = 10 then 9000
when deptno = 20 then 6000
else 0 end as 보너스
from emp;
또는
select ename, deptno , case deptno when 10 then 9000
when 20 then 6000
else 0 end as 보너스
from emp;
문제144. 이름, 보너스를 출력하는데 커미션이 null 이면 보너스를
9000 을 출력하고 커미션이 null 이 아니면 보너스를 5000을
출력하시오 !
select ename, comm, case when comm is null then 9000
else 5000 end as 보너스
from emp;
예제. 이름과 커미션을 출력하는데 커미션이 높은 사원부터 낮은 사원
순으로 출력하시오 !
select ename, comm
from emp
order by comm desc ;
이렇게만 출력하면 null 이 맨 위에 나오면서 보기가 불편해졌습니다.
※ nulls last 또는 nulls first 를 쓸 수 있습니다.
문제145. 아래의 결과에서 보너스 null 값을 맨 아래에 출력되게하시오!
select ename, decode( job, 'PRESIDENT', to_number(null), sal ) as 보너스
from emp
order by 보너스 desc ;
답:
select ename, decode( job, 'PRESIDENT', to_number(null), sal ) as 보너스
from emp
order by 보너스 desc nulls last ;
복습) 함수 :
1. 단일행 함수 : 문자, 숫자, 날짜, 변환, 일반(single row function)
2. 복수행 함수 : max, min, avg, sum, count
( multiple row function )
**하나의 SQL문에 둘은 같이 쓸 수 없다!**
예제. 사원 테이블에서 최대 월급을 출력하시오 !
select max(sal)
from emp;
문제146. 직업이 SALESMAN 인 사원들 중에서의 최대월급을 출력하시오!
select max(sal)
from emp
where job='SALESMAN';
문제147. 우리반 테이블에서 서울에서 사는 학생중에 최대나이를
출력하시오 !
select max(age)
from emp17
where address like '서울%';
문제148. (복습문제) 직업이 SALESMAN, ANALYST 인 사원들중의
최대월급을 출력하시오 !
select max(sal)
from emp
where job in ('SALESMAN', 'ANALYST' );
문제149. 통신사가 KT 인 학생들중에서의 최대나이를 출력하시오 !
( 우리반 테이블 emp17 )
select max(age)
from emp17
where lower(telecom) = 'kt' ;
문제150. 직업이 SALESMAN 인 사원들중에서의 최대월급을 출력하는데
직업도 앞에 같이 나오게 하시오 !
3. select job, --> 여러개가 출력하려고 한다.
max(sal) --> 1개가 출력 되는데
1. from emp
2. where job = 'SALESMAN';
-> 따라서 에러가 발생한다.
4. select job, max(sal)
1. from emp
2. where job='SALESMAN'
3. group by job;
※ group by 절의 역활 : 데이터를 grouping 해주는 역활을 합니다.
앞의 번호는 실행 순서를 나타내는 것.
문제151. 부서번호, 부서번호별 최대월급을 출력하시오 !
문제152. 부서번호, 부서번호별 최대월급을 출력하는데 부서번호가 10,20,30번
순으로 정렬되어서 출력되게하시오 !
※ order by 절을 무조건 맨 마지막에 작성합니다. 실행도 맨 마지막에 됩니다.
※ 함수는 어찌되었든 결과를 리턴해줍니다. (SQLP 시험용)
select max(sal)
from emp
where job='SALESMA';
함수는 WHERE 절의 조건이 false 여도 결과는 리턴이 됩니다.
문제153.아래의 출력되는 결과가 null 값이 맞는지 확인해보시오 !
select nvl( max(sal) , 0 )
from emp
where job='SALESMA';
선택된 레코드가 없다고 하지 않습니다 . null 값이라도 출력합니다.
문제154. 사원 테이블에서 최소월급을 출력하시오 !
select min(sal)
from emp;
문제155. 직업이 SALESMAN 인 사원들중에서의 최소월급을 출력하시오
select min(sal)
from emp
where job='SALESMAN';
문제156. 직업, 직업별 최소월급을 출력하시오 !
select job, min(sal)
from emp
group by job;
문제157. 위의 결과를 다시 출력하는데 직업이 SALESMAN 은 제외하고
출력하시오 !
문제158. 위의 결과를 다시 출력하는데 직업별 최소월급이 높은것부터
출력하시오 !
select job, min(sal) select 보고 싶은 컬럼명
from emp from 테이블명
where job != 'SALESMAN' where 검색조건
group by job group by 그룹핑할 컬럼
order by 2 desc; order by 정렬할 컬럼
문제159. 우리반 테이블에서 성별, 성별별 최소나이를 출력하시오 !
select gender, min(age)
from emp17
group by gender;
문제160. (복습문제) 부서번호, 부서번호별 최소월급을 출력하는데
부서번호가 10 번과 20번만 출력되게하시오 !
select deptno, min(sal)
from emp
where deptno in ( 10, 20 )
group by deptno;
문제161. (복습문제) 우리반 테이블에서 이름의 성씨만 출력하시오 !
select substr( ename, 1, 1 )
from emp17;
문제162. 우리반 테이블에서 성씨, 성씨별 최소나이를 출력하시오 !
select substr( ename, 1, 1 ) , min(age)
from emp17
group by substr( ename, 1, 1 ) ;
문제163. emp 테이블에서 입사한 년도(4자리), 입사한 년도별 최소월급을
출력하시오!
select to_char( hiredate, 'RRRR'), min(sal)
from emp
group by to_char( hiredate, 'RRRR');
문제164. 우리반 테이블에서 통신사, 통신사별 최소나이를 출력하시오!
select telecom, min(age)
from emp17
group by telecom;
설명: 위의 결과는 통신사가 9개나 출력되고 있습니다.
제대로 통신사가 3개만 나오게 해줘야 합니다.
문제165. 위의 문제164번을 다시 수행하는데 통신사를 소문자로 출력
하면서 출력하시오 !
select lower(telecom) , min(age)
from emp17
group by lower(telecom);
문제166. 이름, 통신사를 출력하는데 통신사를 출력할때
소문자로 출력하고 통신사 skt 를 sk 로 출력하시오
( 오늘 배운 decode 함수를 사용해야 합니다.)
select ename, decode( lower(telecom), 'skt', 'sk', lower(telecom) )
from emp17;
문제167. (오늘의 마지막 문제) 아래와 같이 통신사와 통신사별
최소 나이가 출력되게하시오 !
통신사 최소나이
kt 25
lg 25
sk ?
마지막 문제 올리시고 자유롭게 자습 또는 복습하시면 됩니다. ~~
3가지 방법으로~!
select decode(lower(telecom), 'skt', 'sk','lgt', 'lg','lgu+', 'lg',lower(telecom)) as 통신사, MIN(age) as 최소나이
from emp17
group by decode(lower(telecom), 'skt', 'sk','lgt', 'lg','lgu+', 'lg',lower(telecom))
order by 통신사;
SELECT CASE WHEN LOWER(telecom) LIKE 'sk%' THEN TO_CHAR('sk')
WHEN LOWER(telecom) LIKE 'kt%' THEN TO_CHAR('kt')
WHEN LOWER(telecom) LIKE 'lg%' THEN TO_CHAR('lg')
ELSE '0' END"통신사" , MIN(age)"최소나이"
FROM emp17
GROUP BY CASE WHEN LOWER(telecom) LIKE 'sk%' THEN TO_CHAR('sk')
WHEN LOWER(telecom) LIKE 'kt%' THEN TO_CHAR('kt')
WHEN LOWER(telecom) LIKE 'lg%' THEN TO_CHAR('lg')
ELSE '0' END
ORDER BY 1;
SELECT SUBSTR(LOWER(telecom), 1, 2) as 통신사 , MIN(age) as 최소나이
FROM emp17
GROUP BY SUBSTR(LOWER(telecom), 1, 2)
ORDER BY 1 asc ;