오라클 DBMS 정리 03
06 Nov 2018
Reading time ~5 minutes
오라클 DBMS 정리 03 - DML, SELECT
SELECT
SELECT 컬럼명, 컬럼명 alias, 컬럼명 연산자, 함수(컬럼명)
FROM 테이블명 alias
WHERE 검색조건
GROUP BY 그룹묶을 컬럼명
HAVING 그룹으로 묶을 조건
ORDER BY 정렬할 컬럼명
- SELECT 연산자
- 산술연산자 : +, -, *, /, mod()
-
붙임연산자 :
- WHERE 검색조건
- 연산자
- 관계연산자 : >, <, >=, <=, =, !=(<>)
- 논리연산자 : AND, OR
- 연산자
- WHERE/ GROUP BY/ ORDER BY 절은 생략 가능
붙임 연산자(||)
- 컬럼끼리 붙여서 출력하거나 출력 결과를 문장으로 만들어 조회할 때 사용
- 붙임연산자(‘||‘)를 사용하면 분리된 컬럼들을 하나로 합침
SELECT ename||' ('||empno||')님은 '||job||'입니다.' output
FROM emp;
산술 연산자
-- 사원테이블에서 사원번호, 사원명, 연봉, 세금을 조회
-- 단, 세금은 연봉에 3.3% 계산하여 출력
SELECT empno, ename, sal, sal*0.033 tax
FROM emp;
-- 사원번호는 현재 번호에 10을 더한 값으로 출력
SELECT empno, empno+10 new_empno
FROM emp;
-- 컬럼값끼리 연산도 가능
SELECT empno - mgr
FROM emp;
-- dual 테이블은 모든 계정에서 사용할 수 있는 가상테이블, pseudo table(사기 테이블)
-- 입력된 값으로 컬럼을 생성하여 조회
SELECT '오영근' name
FROM dual;
-- 여기서 name은 pseudo column
-- 나눈 나머지 : mod(컬럼명, 나눌값) 함수 사용
SELECT mod(10,2), mod(11,2), mod(3,2), mod(5,2)
FROM dual;
- +,-,*,/
- NULL과 연산 시 결과는 NULL이 됨
관계연산자
-- 사원테이블에서 연봉이 2500보다 작은 사원의 사원번호,
-- 사원명, 매니저번호, 연봉, 입사일, 부서번호 조회
SELECT empno, ename, mgr, sal, hiredate, deptno
FROM emp
WHERE sal<2500;
-- 사원 테이블에서 부서번호가 '30'번인 사원들의
-- 사원번호, 사원명, 직무, 입사일을 조회
SELECT empno, ename, job, hiredate
FROM emp
WHERE deptno=30;
-- 사원테이블에서 부서번호가 20번이 아닌 사원들의
-- 사원번호, 부서번호, 사원명, 직무를 조회
SELECT empno, deptno, ename, job
FROM emp
WHERE deptno<>20;
--WHERE deptno!=20;
- WHERE절, HAVING절 사용
- >, >=, <, <=, =, !=(<>)
- 조회하는 컬럼에 관계연산자를 사용할 수 없음
- 작성 순서는 FROM, WHERE, SELECT
- 미만과 이하, 초과와 이상을 잘 구분해 사용해야 한다(큰 차이!)
NULL 비교 연산자
-- 사원 테이블에서 보너스가 없는 사원의 사원번호, 사원명, 연봉, 보너스 조회
-- null은 관계연산자로 비교할 수 없다
SELECT empno, ename, sal, comm
FROM emp
WHERE comm IS NULL;
-- 보너스가 있는 사원들
SELECT empno, ename, sal, comm
FROM emp
WHERE comm IS NOT NULL AND comm!=0;
논리 연산자
- AND, OR, NOT
- AND : 모든 비교조건이 맞는 레코드를 조회
- OR : 비교조건에 해당하는 모든 레코드를 조회
-- 사원테이블에서 사원번호가 7369 이면서 직무가 clerk인 사원의
-- 사원번호, 사원명, 직무, 입사일, 연봉을 조회
SELECT empno, ename, job, hiredate,sal
FROM emp
WHERE empno=7369 AND job='CLERK';
-- 'clerk'하면 결과 안나옴, 레코드 값에 대해선 대소문자를 가리기 때문!
-- 사원테이블에서 연봉이 1500이상 3000이하인 사원들의
-- 사원번호, 사원명, 직무, 입사일, 연봉 조회
SELECT empno, ename, job, hiredate, sal
FROM emp
WHERE sal >= 1500 AND sal <= 3000;
-- 범위를 검색조건으로 사용할 때에는 BETWEEN을 사용할 수 있다.
SELECT empno, ename, job, hiredate, sal
FROM emp
WHERE sal BETWEEN 1500 AND 3000;
-- 사원 테이블에서 7902, 7839, 7566 매니저의 관리를 받는 사원의
-- 사원번호, 사원명, 매니저번호, 연봉, 입사일 조회
SELECT empno, ename, mgr, sal, hiredate
FROM emp
WHERE mgr=7902 OR mgr=7839 OR mgr=7566;
-- OR는 쉽게 길어지므로 IN()으로 바꿔 쓸 수 있다.
-- 사용법) 컬럼명 IN (값, 값, ...)
SELECT empno, ename, mgr, sal, hiredate
FROM emp
WHERE mgr IN (7902, 7839, 7566);
-- NOT IN()을 사용하면 포함하지 않는 결과를 조회
문자열 연산자
WHERE 컬럼명 LIKE '기호 찾을문자열 기호';
- 와일드카드
- ’%’ - 모든 문자열 (글자수 상관 없음)
- ‘_’ - 하나의 문자열 (글자수에 민감할 때 사용)
- LIKE를 쓰고 와일드카드를 사용하지 않으면 ‘=’와 동일
- 정확히 검색하고자 하는 값을 알 땐 ‘=’, 정확히 모를 땐 LIKE를 사용
-- '김'으로 시작하는 사람을 조회 (문자열로 시작하는)
WHERE name LIKE '김%';
-- '래'로 끝나는 사람을 조회 (문자열로 끝나는)
WHERE name LIKE '%래';
-- 이름에 '정'이 들어있는 사람을 조회 (문자열을 포함하는)
WHERE name LIKE '%정%';
-- 이름이 '정현석'이란 사람도 조회됨(첫글자 또는 끝 글자라도 조회)
-- 이름이 4글자인 사람 조회
WHERE name LIKE '____';
-- 이름이 3글자이며 가운데 글자가 '정'인 사람 조회
WHERE name LIKE '_정_';
-- 김씨이면서 이름이 두자인 사람
WHERE name LIKE '김__';
중복배제
- DISTINCT, GROUP BY로 중복 배제
- DISTINCT 란 키워드를 가지고도 중복 배제 가능
- GROUP BY는 그룹으로 묶는 컬럼 외 컬럼 조회시 에러발생, DISTINCT는 에러가 안남
- GROUP BY는 해당 컬럼을 그룹으로 묶는 것 그룹으로 묶이면 중복이 배제됨
- HAVING엔 그룹화할 조건을 명시
DISTINCT
SELECT DISTINCT deptno
FROM emp;
- 조회하는 컬럼명 앞에 기술
- 조회결과를 생성할 때 같은 값이 존재하는지 판단하여 같은 값이 존재하면 출력하지 않음
ELECT DISTINCT deptno, ename
FROM emp;
- 다른 컬럼과 같이 조회하면 DISTINCT는 모든 컬럼에 적용됨
- 모든 컬럼의 값이 같은 경우에만 중복값을 배제함
- ename에 같은 사람이 없기 때문에 다른 결과라 판단하여 조회함
- DISTINCT를 중복 배제의 목적으로 쓸꺼면 컬럼 하나만 조회하는데 써라
GROUP BY
- 조회 결과를 그룹으로 묶어 출력
- 조회되는 컬럼은 반드시 그룹으로 묶인 컬럼이거나, 집계함수를 사용한 컬럼만 조회 가능
- 다른 컬럼명을 조회시 에러발생
- HAVING절로 그룹으로 묶일 조건을 설정할 수 있음
-- 사원 테이블에서 매니저번호를 조회
SELECT mgr
FROM emp;
-- 단, 중복되는 매니저번호는 출력하지 않음
-- DISTINCT로는 집계함수를 사용하여 그룹별 집계를 보여줄 수 없음
SELECT DISTINCT mgr
FROM emp;
-- DISTINCT와 GROUP BY의 결과는 모두 중복배제로 같다
SELECT mgr
FROM emp
GROUP BY mgr;
-- error!
SELECT mgr, ename
FROM emp
GROUP BY mgr;
-- 그룹으로 묶인 컬럼이 아닌 컬럼을 조회하려 했기 때문에!
SELECT mgr, ename
FROM emp
GROUP BY mgr, ename;
-- 이러면 에러는 없지만 아래 DISTINCT 결과와 동일
SELECT DISTINCT deptno, ename
FROM emp;
- 일반적으로 하나의 컬럼만 그룹으로 묶는다.
ORDER BY
- 기본 정렬은 오름차순 정렬(ASC - ascending, 생략가능)
- 내림차순은 DES(desending, 명시)
- 입력된 레코드를 오름차순, 내림차순으로 정렬하여 보여줄 때 사용
- SELECT 가장 마지막에 기술
- 모든 값을 정렬할 수 있음
-- ASC(오름차순)는 생략가능(생략해서 잘 안씀)
ORDER BY 정렬할컬럼명 (ASC), 두번째정렬할컬럼명, ...;
-- DESC(내림차순)는 명시
ORDER BY 정렬할컬럼명 DESC;
- 문자열이 숫자형태를 갖는 경우 자릿수로 정렬을 함
... 어느 테이블 구조
num VARCHAR2(30)
...
-- num에 1, 11, 25, 1001, 3, 209, 5란 데이터가 들어 있을 때
ORDER BY num;
-- 숫자가 아닌 문자열을 정렬하면 앞에 1인걸 먼저 찾음
-- 1, 1001, 11, 209, 25, 3, 5 이렇게 정렬됨
-- 숫자의 크기로 정렬되는게 아니라 자릿수에 대한 정렬을 수행
- 윈도우에서 날짜별 폴더를 만들 시 위와 같이 정렬됨
- 15폴더보다 1015일 폴더가 위로 정렬됨
- 두번째 자리수 5보다 0이 더 작기 때문에
- 0105, 1015 이런식으로 폴더명을 변경하면 잘 정렬됨
- 문자열이 숫자형태를 가질 경우 정렬은 자리수가 같아야 숫자 정렬이 잘 된다
- 15폴더보다 1015일 폴더가 위로 정렬됨
- 문자열이 숫자형태를 가질 경우 0을 넣어 자리수를 맞춘다!