A={1,2,3,4,5} 이렇게 넣었다.
B={3,5,6,7,8,9,10} 이렇게 넣었다.
1. 단일행 서브쿼리
2. 다중행 서브쿼리
3. 다중열 서브쿼리
4. 다중행,다중열 서브쿼리
5. 상관 서브쿼리
6. 스칼라 서브쿼리
-> 이거 6개 다하면 DBA로 가는거고 우린 단일행 서브쿼리만 해보겠다.
-> 결과가 단일행이면 단일행 서브쿼리, 이런식으로 나온다.
1. 윤은해와 급여가 같은 사원들을 검색해서, 사원번호, 이름, 급여를 출력(단, 윤은해는 출력되면 안됨)
2. EMPLOYEE테이블에서 기본급여가 가장 많은사람과, 가장 적은사람의 정보를 사번, 사원명, 기본급여를 출력
3. D1, D2부서에 근무하는 사원들 중에서 기본급여가 D5부서 직원들의 '평균월급'보다 많은 사람들만 부서번호, 사원명, 월급을 출력
4. 기술지원부에 속한 사람들의 이름, 부서코드, 급여 출력
중요한건 테이블과 시퀀스이다.
COMMENTS는 주석을 처리한것이다.
ID 컬럼 -> NULL은 허용하지 않을꺼야 라는 제약을 주겠다.
NOT NULL : 데이터의 NULL을 허용하지 않습니다.
UNIQUE : 중복된 값을 허용하지 않습니다.
ID는 반드시 들어가야하고 null값도 허용안되고 다른사람 사용하면 가입도안되게해야한다.
쇼핑에서는 쇼핑번호가 프라이머리키가될것이다.
이아이디를 참조해와서 쓸것이다.
쇼핑의 ID는 외래키가된다. 왜냐면 멤버에서 참조해올것이기 때문이다.
-> NOT NULL, UNIQUE의 두가지 의미를 가지고 있다.
가질 수 있다.
===========================================================================================
===========================================================================================
--20180821
/*
부서코드가 D5인 사람의 EMP_ID, EMP_NAME, DEPT_CODE, SALARY 출력
*/
select * from employee;
select emp_id, emp_name, dept_code, salary from employee where dept_code='D5';
/*
salary가 300만원보다 큰 사람의 EMP_ID, EMP_NAME, DEPT_CODE, SALARY
*/
select emp_id, emp_name, dept_code, salary from employee where salary>=3000000;
/*
UNION
중복된 데이터를 제거하고 첫번째 컬럼기준으로 오름차순 정렬
--심봉선이랑 데프콘이란 직원은 겹치는 거라서 중복된데이터를 제거한것이다.
*/
select emp_id, emp_name, dept_code, salary from employee where dept_code='D5'
UNION
select emp_id, emp_name, dept_code, salary from employee where salary>=3000000;
/*
UNION ALL
--중복된 데이터 제거작업이 없고, 정렬도 없이 그대로 데이터를 합쳐서 보여줌
두개 합친거 다보여준다.
*/
select emp_id, emp_name, dept_code, salary from employee where dept_code='D5'
UNION ALL
select emp_id, emp_name, dept_code, salary from employee where salary>=3000000;
/*
INTERSECT
--공통된 요소만 보여줌
*/
select emp_id, emp_name, dept_code, salary from employee where dept_code='D5'
INTERSECT
select emp_id, emp_name, dept_code, salary from employee where salary>=3000000;
/*
MINUS
선행 SELECT 결과에서 다음 SELECT 결과와 겹치는 부분을 제외한 나머지
*/
select emp_id, emp_name, dept_code, salary from employee where dept_code='D5'
MINUS
select emp_id, emp_name, dept_code, salary from employee where salary>=3000000;
/*
@ GROUPING SETS
-> GROUP BY + UNION ALL
-> 그룹별로 처리된 여러개의 SELECT문을 하나로 합친결과 반환
-> GROUPING SETS (col1, col2)을 GROUP by 절에 명시
-> 괄호안에 있는 표현식별로 집계가 이루어짐
-> SET OPERATIOR을 사용한 결과랑 동일한 결과를 얻을 수 있음
*/
select dept_code, job_code, count(*) from employee
group by grouping sets (dept_code,job_code);
select dept_code, count(*) from employee
group by dept_code;
select job_code, count(*) from employee
group by job_code;
select dept_code, null "JOB_CODE", count(*) from employee
group by dept_code;
--강제로 만들어서 결과를 볼려는 것이다.
select dept_code, null "JOB_CODE", count(*)
from employee group by dept_code
UNION ALL
select null "dept_code", job_code, count(*)
from employee group by job_code;
--이걸 쉽게 하기위해서 만든게 grouping sets 이다.
select dept_code, job_code, count(*) from employee
group by grouping sets (dept_code,job_code);
--------------------------------------------------------------------
select * from employee where(select * from department);
/*
전지연 직원의 관리자 이름을 출력 -> 서브쿼리로 짜보기
*/
--1. 전지연 직원의 MANAGER_ID알아야 한다.
select MANAGER_ID from employee where emp_name='전지연';
-- ->214가 나온다.
--2. 전지연직원의 MANAGER_ID와 일치하는 EMP_ID를 알아낸 후 이름을 출력
select EMP_NAME FROM EMPLOYEE where emp_id=214;
-- -> 이렇게 하면 방명수라는 매니저의 이름을 알아낼 수 있다.
/*
-> 1번 2번 두가지 과정을 거쳐야만 가능하다.
-> 서브쿼리를 이용하면 가능하다.
*/
select emp_name from employee
where EMP_ID=(SELECT MANAGER_ID FROM EMPLOYEE where EMP_NAME='전지연');
--ex) 전 직원의 평균 급여보다 많은 급여를 받고있는 직원의 사번, 이름, 직급코드 급여를 조회
--서브쿼리 없다고 생각해보면 어떻게 할꺼냐면 평균급여를 구할것이다.
select AVG(salary) from employee;
--1. 평균급여를 구하기
select EMP_ID, EMP_NAME, JOB_CODE, SALARY FROM EMPLOYEE
where SALARY>3047662;
--2.아까 평균급여나온결과로인해 값 산출해나가기
select EMP_ID, EMP_NAME, JOB_CODE, SALARY FROM EMPLOYEE
where SALARY>(select AVG(salary) from employee);
--아까랑 동일하게 나올 것이다.
/*
1. 윤은해와 급여가 같은 사원들을 검색해서, 사원번호, 이름, 급여를 출력(단, 윤은해는 출력
되면 안됨)
2. EMPLOYEE테이블에서 기본급여가 가장 많은사람과, 가장 적은사람의 정보를 사번, 사원명, 기본급여를 출력
3. D1, D2부서에 근무하는 사원들 중에서 기본급여가 D5부서 직원들의
'평균월급'보다 많은 사람들만 부서번호, 사원명, 월급을 출력
4. 기술지원부에 속한 사람들의 이름, 부서코드, 급여 출력
*/
--1. 윤은해와 급여가 같은 사원들을 검색해서, 사원번호, 이름, 급여를 출력(단, 윤은해는 출력되면 안됨)
select * from employee;
select emp_id, emp_name, salary from employee where salary=
(select salary from employee where EMP_NAME='윤은해') and emp_name!='윤은해' ;
--2. EMPLOYEE테이블에서 기본급여가 가장 많은사람과, 가장 적은사람의 정보를 사번, 사원명, 기본급여를 출력
select emp_id,emp_name,salary from employee where salary=(select max(salary) from employee) or salary=(select min(salary) from employee);
--3. D1, D2부서에 근무하는 사원들 중에서 기본급여가 D5부서 직원들의 '평균월급'보다 많은 사람들만 부서번호, 사원명, 월급을 출력
select * from employee;
select dept_code, emp_name, salary from employee where (DEPT_CODE in ('D1','D2')) and salary>(select avg(salary) from employee where dept_code='D5');
--4. 기술지원부에 속한 사람들의 이름, 부서코드, 급여 출력
select * from employee;
select * from DEPARTMENT;
--방법1
select e.emp_name, e.dept_code, e.salary from employee e, department d where (d.dept_title='기술지원부') and (e.dept_code=d.dept_id);
--방법2
select e.emp_name, e.dept_code, e.salary from employee e, department d
where d.dept_title=(select dept_title from department where dept_title='기술지원부') and (e.dept_code=d.dept_id);
--방법3
select emp_name, dept_code, salary from employee where dept_code=(select dept_id from department where dept_id='D8');
--================================================================
CREATE TABLE MEMBER( --멤버테이블 생성
MEMBER_ID VARCHAR2(20), --MEMBER_ID 컬럼생성
MEMBER_PWD VARCHAR2(20), --MEMBER_PWD 컬럼생성
MEMBER_NAME VARCHAR2(20) --MEMBER_NAME 컬럼생성
);
select * from member;
--COMMENT는 주석을 처리한것인데 이건 주석 을 추가하는 것이다.
COMMENT ON COLUMN MEMBER.MEMBER_ID IS '회원아이디';
--테이블만들고 주석 처리하면 훨씬 좋아질 것이다.
COMMENT ON COLUMN MEMBER.MEMBER_PWD IS '비밀번호';
COMMENT ON COLUMN MEMBER.MEMBER_NAME IS '회원이름';
/*
CONSTRAINT_TYPE
P : PRIMARY KEY
R : FOREIGN KEY
C : CHECK 또는 NOT NULL
U : UNIQUE
*/
select CONSTRAINT_NAME, CONSTRAINT_TYPE FROM USER_CONSTRAINTS
WHERE TABLE_NAME='EMPLOYEE';
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM USER_CONS_COLUMNS
WHERE TABLE_NAME='EMPLOYEE'
UNION
SELECT TABLE_NAME, CONSTRAINT_NAME, CONSTRAINT_TYPE FROM USER_CONSTRAINTS
WHERE TABLE_NAME='EMPLOYEE' order by 3;
CREATE TABLE USER_NOCONS(
USER_NO NUMBER,
USER_ID VARCHAR2 (20),
USER_PWD VARCHAR2 (30),
USER_NAME VARCHAR2 (30),
GENDER VARCHAR2(30),
PHONE VARCHAR2(30),
EMAIL VARCHAR2(50)
);
--USER_NOCONS 테이블을 만들기
--데이터를 삽입해보자
INSERT INTO USER_NOCONS VALUES
(1,'user01','pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
INSERT INTO USER_NOCONS VALUES
(2,NULL,NULL,NULL,NULL,'010-1234-5678','hong123@kh.or.kr');
--데이터 넣은값 조회하기
select * from USER_NOCONS;
--이렇게 해버리면 null값이들어가지는데 말도안되게들어가진다.
/*
@ NOT NULL
-> 해당 컬럼에 반드시 값이 기록되어야 하는 경우
-> 특정 컬럼에 값을 저장하거나 수정할때 NULL을 허용하지 않도록 제한
*/
CREATE TABLE USER_NOTNULL(
USER_NO NUMBER NOT NULL,
USER_ID VARCHAR2 (20) NOT NULL,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2 (30) NOT NULL,
GENDER VARCHAR2 (10) NOT NULL,
PHONE VARCHAR2 (30),
EMAIL VARCHAR2 (50)
);
---------------------------------------------------------------
INSERT INTO USER_NOTNULL VALUES
(1,'user01','pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
INSERT INTO USER_NOTNULL VALUES
(2,NULL,NULL,NULL,NULL,'010-1234-5678','hong123@kh.or.kr');
--넣을려고 하면 안넣어진다. 왜냐하면 null값이기 때문이다.
---------------------------------------------------------------
INSERT INTO USER_NOTNULL VALUES
(2,NULL,'pass02','홍길','남','010-1234-5678','hong123@kh.or.kr');
--넣을려고 하면 안넣어진다. 왜냐하면 null값이기 때문이다.
---------------------------------------------------------------
select * from USER_NOTNULL;
--이렇게 하면 하나밖에 안들어가져 있다.
/*
@ UNIQUE
-> 컬럼에 입력 값에 대해 중복을 제한하는 제약조건
*/
insert into user_nocons values
(3,'user01','pass02','홍길','남','010-1234-5678','hong123@kh.or.kr');
select * from USER_nocons;
-----------------------------------------------------------
/*
@ UNIQUE
-> 컬럼에 입력 값에 대해 중복을 제한하는 제약조건
*/
CREATE TABLE USER_UNIQUE(
USER_NO NUMBER,
USER_ID VARCHAR2 (20) UNIQUE,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2 (30),
GENDER VARCHAR2 (10),
PHONE VARCHAR2 (30),
EMAIL VARCHAR2 (50)
); -- 컬럼레벨에 저장하는것
CREATE TABLE USER_UNIQUE(
USER_NO NUMBER,
USER_ID VARCHAR2 (20),
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2 (30),
GENDER VARCHAR2 (10),
PHONE VARCHAR2 (30),
EMAIL VARCHAR2 (50)
UNIQUE (USER_ID)
); --테이블레벨에 저장하는것이라고 한다.
INSERT INTO USER_UNIQUE VALUES
(1,'user01','pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
INSERT INTO USER_UNIQUE VALUES
(2,'user01','pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
--아이디 겹쳐서 저장할려 하면 안된다. -> 에러가 난다. UNIQUE때문이다.
INSERT INTO USER_UNIQUE VALUES
(2,NULL,'pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
INSERT INTO USER_UNIQUE VALUES
(2,NULL,'pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
--아이디 겹쳐서 저장할려 하면 안된다. -> 에러가 난다. UNIQUE때문이다.
select * from USER_UNIQUE;
--null값일경우 중복된 데이터가 들어갈 수 있다.
-------------------------------------------------------
/*
@ PRIMARY KEY
-> 테이블에서 한 행의 정보를 구분하기 위한 고유식별자 역할
-> NOT NULL, UNIQUE의 두가지 의미를 가지고 있다.
-> 테이블당 1개만 설정 가능
*/
CREATE TABLE USER_PRIMARYKEY(
USER_NO NUMBER PRIMARY KEY, --테이블당1개만설정가능, notnull과 unique두가지 의미 가지고 있다.
USER_ID VARCHAR2 (20) UNIQUE, --고유식별자역할
USER_PWD VARCHAR2(30) NOT NULL, --null값이 안들어가도록 할것이다.
USER_NAME VARCHAR2 (30),
GENDER VARCHAR2 (10),
PHONE VARCHAR2 (30),
EMAIL VARCHAR2 (50)
);
INSERT INTO USER_PRIMARYKEY VALUES
(1,'user01','pass01','홍길동','남','010-1234-5678','hong123@kh.or.kr');
INSERT INTO USER_PRIMARYKEY VALUES
(1,'user02','pass02','홍길','남','010-1234-5678','hong123@kh.or.kr');
--primarykey로지정한 1이 동일해서 unique조건이 작동된것이다.
INSERT INTO USER_PRIMARYKEY VALUES
(null,'user02','pass02','홍길','남','010-1234-5678','hong123@kh.or.kr');
--null도 못들어간다.
INSERT INTO USER_PRIMARYKEY VALUES
(2,'user02','pass02','홍길','남','010-1234-5678','hong123@kh.or.kr');
--조건을 다 만족시켰기 때문에 다들어가진다.
select * from USER_PRIMARYKEY;
--------------------------------------------------
CREATE TABLE USER_PRIMARYKEY2(
USER_NO NUMBER,
USER_ID VARCHAR2 (20) UNIQUE, --고유식별자역할
USER_PWD VARCHAR2(30) NOT NULL, --null값이 안들어가도록 할것이다.
USER_NAME VARCHAR2 (30),
GENDER VARCHAR2 (10),
PHONE VARCHAR2 (30),
EMAIL VARCHAR2 (50),
PRIMARY KEY(USER_NO, USER_ID)
); --2개의 키가 묶여서 프라이머리 키가 되는 것이다, 묶어서 쓸수 있다.
--이렇게 하면 프라이머리키가 1나밖에 안되기때문에 이렇게 설정하면 복합키라고도 부른다.
select * from USER_PRIMARYKEY2;
/*
@ FOREIGN KEY(외래키)
-> 참조 무결성을 유지하기 위한 제약조건
-> 참조된 다른 테이블이 제공하는 값만 사용할 수 있도록 제한을 거는것
-> 참조되는 컬럼과 참조된 컬럼을 통해서 테이블간의 관계 형성
-> 해당 컬럼 값은 참조되는 테이블의 컬럼 값 중 하나와 일치하거나 NULL을
가질 수 있다.
*/
CREATE TABLE SHOP_MEMBER(
USER_NO NUMBER UNIQUE,
USER_ID VARCHAR2 (20) PRIMARY KEY,
USER_PWD VARCHAR2(30) NOT NULL,
USER_NAME VARCHAR2 (30),
GENDER VARCHAR2 (10),
PHONE VARCHAR2 (30),
EMAIL VARCHAR2 (50)
);
INSERT INTO SHOP_MEMBER VALUES
(1,'user01','pass01','홍길동','남','010-1111-2222','hong@kh.or.kr');
INSERT INTO SHOP_MEMBER VALUES
(2,'user02','pass02','이순신','남','010-2222-3333','lee@kh.or.kr');
INSERT INTO SHOP_MEMBER VALUES
(3,'user03','pass03','신사임당','여','010-3333-4444','shin@kh.or.kr');
INSERT INTO SHOP_MEMBER VALUES
(4,'user04','pass04','안중근','남','010-4444-5555','ahn@kh.or.kr');
INSERT INTO SHOP_MEMBER VALUES
(5,'user05','pass05','유관순','여','010-5555-6666','you@kh.or.kr');
select * from shop_member;
--잘등록되어있는지 확인해보기
create table SHOP_BUY(
BUY_NO NUMBER PRIMARY KEY,
USER_ID VARCHAR2(20) REFERENCES SHOP_MEMBER(USER_ID),
PRODUCT_NAME VARCHAR2(20) ,
REG_DATE DATE
);
INSERT INTO SHOP_BUY VALUES (1,'user01','축구화',sysdate);
INSERT INTO SHOP_BUY VALUES (2,'user02','축구장',sysdate);
INSERT INTO SHOP_BUY VALUES (3,'user03','축구공',sysdate);
INSERT INTO SHOP_BUY VALUES (4,NULL,'축구',sysdate);
INSERT INTO SHOP_BUY VALUES (5,'만수르','깡통',sysdate); -- userID가 없기때문에 삽입이안된다.
--member테이블에 만수르라는 ID가없다. 그래서 넣을 수가 없다.
--null은 되는게 not null이 아니기 때문에 비회원구매를 생각하면된다.