SQL활용 2022/03/22(SQL 작성하기) JOIN, 내장함수, 페이지네이션

inner join

-- SELECT * FROM 테이블1, 테이블2 WHERE 테이블1.컬럼=테이블2.컬럼;

-- ANSI SQL( oracle, mysql, mssql...)어떤 데이터 베이스에서도 사용 가능
-- SELECT * FROM 테이블1 INNER JOIN 테이블2 ON 테이블1.컬럼=테이블2.컬럼;

-- 내장함수( CURRENT_DATE, TO_CHAR)


SELECT * FROM ITEM1;
SELECT * FROM MEMBER1;
SELECT * FROM ORDER1;

-- inner join
-- SELECT * FROM 테이블1, 테이블2 WHERE 테이블1.컬럼=테이블2.컬럼;

-- ANSI SQL( oracle, mysql, mssql...)어떤 데이터 베이스에서도 사용 가능
-- SELECT * FROM 테이블1 INNER JOIN 테이블2 ON 테이블1.컬럼=테이블2.컬럼;


-- 테이블 조회 후 view로 만들기
CREATE OR REPLACE VIEW ORDER1VIEW AS
SELECT ITEMORDER1.*, MEMBER1.USERNAME, MEMBER1.USERADDR 
FROM MEMBER1,(
    SELECT 
        ITEM1.ITEMNAME, ITEM1.ITEMPRICE, ORDER1.* 
    FROM 
        ITEM1,ORDER1 
    WHERE 
        ITEM1.ITEMNO = ORDER1.ORDITEM) ITEMORDER1
WHERE MEMBER1.USERID = ITEMORDER1.ORDID;

-- VIEW는 조회만 가능(ORDER1, MEMBER1, ITEM1)
SELECT * FROM ORDER1VIEW;

INSERT INTO ORDER1( ORDNO, ORDCNT, ORDDATE, ORDITEM, ORDID )
    VALUES( SEQ_ORDER1_ORDNO.NEXTVAL, '1000', CURRENT_DATE, 1005, 'BBB' );

COMMIT;

-- left outer join(왼쪽 전체 + 오른쪽 일치하는 것만)
SELECT * FROM ITEM1, ORDER1 WHERE ITEM1.ITEMNO = ORDER1.ORDITEM(+);

-- ANSI SQL
-- SELECT * FROM 테이블1 LEFT OUTER JOIN 테이블2 ON 테이블1.컬럼 = 테이블2.컬럼;
SELECT * FROM ITEM1 LEFT OUTER JOIN ORDER1 ON ITEM1.ITEMNO = ORDER1.ORDITEM;

INSERT INTO MEMBER1( USERID, USERPW, USERNAME, USERAGE, USERDATE, USERADDR )
    VALUES( 'DDD', 'DDD', 'DDD', '30', CURRENT_DATE, '부산' );
    
-- right outer join
SELECT * FROM ORDER1, MEMBER1 WHERE ORDER1.ORDID(+) = MEMBER1.USERID;
-- ANSI SQL
-- SELECT * FROM 테이블1 RIGHT OUTER JOIN 테이블2 ON 조건;
SELECT * FROM ORDER1 RIGHT OUTER JOIN MEMBER1 ON ORDER1.ORDID(+) = MEMBER1.USERID;

-- FULL OUTER JOIN
-- ANSI SQL만 가능함.
SELECT * FROM ORDER1 FULL OUTER JOIN MEMBER1 ON ORDER1.ORDID = MEMBER1.USERID;

-- 3000원 이상
SELECT 
    ITEM1.ITEMNAME, ITEM1.ITEMPRICE, ORDER1.* 
FROM 
    ITEM1,ORDER1 
WHERE 
    ITEM1.ITEMNO = ORDER1.ORDITEM 
AND 
    ITEM1.ITEMPRICE >= 3000;

-- 3000원 이상    
SELECT 
    ITEM1.ITEMNAME, ITEM1.ITEMPRICE, ORDER1.*
FROM 
    ITEM1 INNER JOIN ORDER1 
ON
    ITEM1.ITEMNO=ORDER1.ORDITEM
WHERE 
    ITEM1.ITEMPRICE >= 3000;

SELECT * FROM DEPARTMENT;

INSERT INTO DEPARTMENT(NO, NAME, AREA) VALUES(101 , '영업부', '');
INSERT INTO DEPARTMENT(NO, NAME, AREA) VALUES(102 , '총무부', '');
INSERT INTO DEPARTMENT(NO, NAME, AREA) VALUES(103 , '기획부', '');
INSERT INTO DEPARTMENT(NO, NAME, AREA) VALUES(104 , '홍보부', '');
COMMIT; -- 또는 ROLLBACK

SELECT * FROM EMPLOYEE;
CREATE SEQUENCE SEQ_EMP_NO START WITH 1001 INCREMENT BY 1 NOMAXVALUE NOCACHE;

INSERT INTO EMPLOYEE(NO, NAME, DEPTNO, PEMPNO, POSITION, PAY, REGDATE) 
VALUES(SEQ_EMP_NO.NEXTVAL,'가나다3', 104, NULL, '부장', 3000000, CURRENT_DATE);

INSERT INTO EMPLOYEE(NO, NAME, DEPTNO, PEMPNO, POSITION, PAY, REGDATE) 
VALUES(SEQ_EMP_NO.NEXTVAL,'나다라3', 104, NULL, '과장', 2000000, CURRENT_DATE);

INSERT INTO EMPLOYEE(NO, NAME, DEPTNO, PEMPNO, POSITION, PAY, REGDATE) 
VALUES(SEQ_EMP_NO.NEXTVAL,'다라마3', 104, NULL, '차장', 3000000, CURRENT_DATE);

INSERT INTO EMPLOYEE(NO, NAME, DEPTNO, PEMPNO, POSITION, PAY, REGDATE) 
VALUES(SEQ_EMP_NO.NEXTVAL,'라마바3', 104, NULL, '대리', 2000000, CURRENT_DATE);

ROLLBACK;
COMMIT;

-- 내장함수( CURRENT_DATE, TO_CHAR)
SELECT 
    NO 번호, NAME 이름, 
    PAY 급여, TO_CHAR(PAY, '999,999,999') 급여1 ,
    REGDATE 날짜, TO_CHAR(REGDATE, 'YYYY"년"MM-DD HH24:MI:SS')날짜1
FROM EMPLOYEE;

-- 부서테이블의 영업부는 지역을 대전으로, 총무부는 서울, 나머지는 부산으로 설정
UPDATE DEPARTMENT SET AREA =
    CASE 
        WHEN (NAME = '영업부' ) THEN '대전'
        WHEN (NAME = '총무부' ) THEN '서울'        
        ELSE '부산'
    END;

-- 사원테이블에서 번호, 이름, 직급을 번호 순으로 내림차순 하여 조회
SELECT NO 번호, NAME 이름, POSITION 직급
    FROM EMPLOYEE ORDER BY NO DESC;

-- 사원테이블에서 급여가 0~200이면 세금이 5%, 201~300 10%, 나머지는 15%로 표시
-- (번호, 이름, 급여, 세금)
SELECT NO 번호, NAME 이름, PAY 급여, 
CASE 
    WHEN (PAY >=0 AND PAY<=200) THEN PAY*0.05 
    WHEN (PAY >=201 AND PAY<=300) THEN PAY*0.1 
    ELSE PAY*0.15
END 세금 
FROM EMPLOYEE;

-- 사원테이블에서 영업부와 총무부만 이름으로 오름차순 조회
SELECT * FROM EMPLOYEE WHERE DEPTNO IN ('101','102') ORDER BY DEPTNO ASC;    
    
-- 사원테이블과 부서 테이블을 inner join하여 조회 
-- (번호, 이름, 급여, 부서명, 지역)
SELECT E.NO 번호, E.NAME 이름, E.PAY, D.NAME 부서명, D.AREA 지역 
    FROM DEPARTMENT D, EMPLOYEE E WHERE  D.NO = E.DEPTNO; 

-- 학생 5명 등록
SELECT STDNO 학번, STDNAME 이름 FROM STUDENT1;

CREATE SEQUENCE SEQ_STD_CODE START WITH 101 INCREMENT BY 1 NOMAXVALUE;

INSERT INTO STUDENT1 (STDNO, STDNAME)
    VALUES( SEQ_STD_CODE.NEXTVAL, '마사아');

ROLLBACK;
COMMIT;

-- 교수 3명 등록
SELECT PRONO 교수번호, PRONAME 교수명 FROM PROFESSOR1;

CREATE SEQUENCE SEQ_PRO_CODE START WITH 1001 INCREMENT BY 1 NOMAXVALUE;

INSERT INTO PROFESSOR1 (PRONO, PRONAME, PROPHONE)
    VALUES( SEQ_PRO_CODE.NEXTVAL, '교수3', 0 );

ROLLBACK;
COMMIT;

-- 교과목 3개 개설
SELECT SUBCODE 과목코드, SUBNAME 과목명, PRONO 교수번호, CLANO 강의실 FROM SUBJECT1;

CREATE SEQUENCE SEQ_CLS_CODE START WITH 10001 INCREMENT BY 1 NOMAXVALUE;

INSERT INTO SUBJECT1 (SUBCODE, SUBNAME, PRONO, CLANO)
    VALUES( SEQ_CLS_CODE.NEXTVAL, '과목3', 1003, 13 );

-- 강의실
SELECT CLANO 강의실, CLAADDR 위치 FROM CLASSROOM1;

CREATE SEQUENCE SEQ_CLA_CODE START WITH 11 INCREMENT BY 1 NOMAXVALUE;

INSERT INTO CLASSROOM1 (CLANO, CLAADDR) VALUES(SEQ_CLA_CODE.NEXTVAL, '102호');
  
-- 수강  
SELECT CURNO 수강번호, STDNO 학번, SUBCODE 과목코드 FROM COURSE1;

INSERT INTO COURSE1 (CURNO, STDNO, SUBCODE) VALUES (1, 101, 10008 );
INSERT INTO COURSE1 (CURNO, STDNO, SUBCODE) VALUES (2, 102, 10009 );
INSERT INTO COURSE1 (CURNO, STDNO, SUBCODE) VALUES (3, 103, 10010 );
INSERT INTO COURSE1 (CURNO, STDNO, SUBCODE) VALUES (4, 104, 10009 );
INSERT INTO COURSE1 (CURNO, STDNO, SUBCODE) VALUES (5, 105, 10008 );

-- 전체 학생목록 (검색어 포함, 페이지네이션)
SELECT * FROM(
    SELECT 
        S.*,
        ROW_NUMBER() OVER (ORDER BY STDNO DESC) ROWN
    FROM 
        STUDENT1 S
    WHERE
        STDNAME LIKE '%' ||''||'%')
WHERE ROWN BETWEEN 1 AND 3;

-- 학생테이블에 컬럼 추가
-- STDCLS : VARCHAR2(1) 반코드('A','B','C')
-- SCOREKOR : NUMBER(3)
-- SCOREENG : NUMBER(3)
-- SCOREMATH : NUMBER(3)
-- REGDATE : DATE
ALTER TABLE STUDENT1 ADD STDCLS VARCHAR2(1) DEFAULT 'A';
ALTER TABLE STUDENT1 ADD SCOREKOR NUMBER(3) DEFAULT 90;
ALTER TABLE STUDENT1 ADD SCOREENG NUMBER(3) DEFAULT 80;
ALTER TABLE STUDENT1 ADD SCOREMATH NUMBER(3) DEFAULT 70;
ALTER TABLE STUDENT1 ADD REGDATE DATE DEFAULT CURRENT_DATE;


INSERT INTO STUDENT1(STDNO, STDNAME, STDCLS, SCOREKOR, SCOREENG, SCOREMATH, REGDATE) 
    VALUES (SEQ_STD_CODE.NEXTVAL, '라', 'C', 100, 20, 30, CURRENT_DATE);
INSERT INTO STUDENT1(STDNO, STDNAME, STDCLS, SCOREKOR, SCOREENG, SCOREMATH, REGDATE) 
    VALUES (SEQ_STD_CODE.NEXTVAL, '사', 'C', 80, 100, 90, CURRENT_DATE);
INSERT INTO STUDENT1(STDNO, STDNAME, STDCLS, SCOREKOR, SCOREENG, SCOREMATH, REGDATE) 
    VALUES (SEQ_STD_CODE.NEXTVAL, '바', 'C', 40, 80, 100, CURRENT_DATE);
    
SELECT * FROM STUDENT1;  

-- 그룹, 반별 학생 수( COUNT(*) )
SELECT STDCLS, COUNT(*) FROM STUDENT1 GROUP BY(STDCLS);

-- 반별 합계
SELECT STDCLS 반, SUM(SCOREKOR) 국어합계 FROM STUDENT1 GROUP BY(STDCLS);

-- 반별 평균(AVG), 반올림 (ROUND(숫자, 자리수))
SELECT 
    STDCLS 반, 
    ROUND( AVG(SCOREKOR), 1) 국어평균,
    ROUND( AVG(SCOREENG), 1) 영어평균,
    ROUND( AVG(SCOREMATH), 1) 수학평균
FROM STUDENT1 GROUP BY(STDCLS);

-- 1. 수학 점수가 50점 이상인 학생들의 반별 평균점수 구하기
SELECT STDCLS, ROUND( AVG(SCOREMATH), 1) 수학평균
FROM STUDENT1 WHERE SCOREMATH >=50 GROUP BY (STDCLS);

-- 2. 반별 평균 수학점수가 50점 이상인것
SELECT STDCLS, ROUND( AVG(SCOREMATH), 1) 수학평균
FROM STUDENT1 GROUP BY (STDCLS) HAVING ROUND( AVG(SCOREMATH), 1)>=50 ;

-- 3. 분별 합계
SELECT 
    TO_CHAR(REGDATE, 'YYYY-MM-DD HH24:MI') 시간,
    COUNT(*) 개수    
FROM STUDENT1 
GROUP BY (TO_CHAR(REGDATE, 'YYYY-MM-DD HH24:MI'));

SELECT * FROM ORDER1;
SELECT * FROM ITEM1;
SELECT * FROM MEMBER1;

-- INNER JOIN
-- SELECT * FROM 테이블1, 테이블2 WHERE 테이블1.컬럼=테이블2.컬럼;
SELECT * FROM ITEM1, ORDER1 WHERE ITEM1.ITEMNO = ORDER1.ORDITEM;

SELECT * FROM ORDER1, MEMBER1 WHERE ORDER1.ORDID = MEMBER1.USERID;

SELECT ORDITEM FROM(
    SELECT 
        ITEMORDER1.*, MEMBER1.USERNAME, MEMBER1.USERADDR
    FROM MEMBER1,(
        SELECT 
            ITEM1.ITEMNAME,ITEM1.ITEMPRICE, ORDER1.*
        FROM 
            ITEM1, ORDER1 
        WHERE 
            ITEM1.ITEMNO = ORDER1.ORDITEM) ITEMORDER1 
    WHERE MEMBER1.USERID = ITEMORDER1.ORDID) ORDER1VIEW
GROUP BY (ORDITEM);

-- 물품별 주문 수량 합계
SELECT ITEM1.ITEMNO 물품코드, SUM(ORDCNT) 주문수량합계 
    FROM ITEM1, ORDER1 WHERE ITEM1.ITEMNO = ORDER1.ORDITEM
GROUP BY (ITEM1.ITEMNO);
    
SELECT * FROM ORDER1;
SELECT * FROM ITEM1;
SELECT * FROM MEMBER1;

-- 물품별 재고 수량 합계
SELECT * FROM ORDER1 O, ITEM1 I WHERE O.ORDITEM=I.ITEMNO;

SELECT ITEMNO 물품코드, SUM(ITEMQTY)재고수량합계  FROM ITEM1 GROUP BY(ITEMNO);

SELECT I.ITEMNO 물품코드, SUM(I.ITEMQTY) 재고수량합계 
FROM ORDER1 O, ITEM1 I 
WHERE O.ORDITEM=I.ITEMNO GROUP BY(I.ITEMNO);

-- 재고수량이 100개 이하인 물품 개수
SELECT COUNT(*) 개수 FROM ITEM1 WHERE ITEMQTY <=100;

-- 시간대별 주문수량 합계
SELECT 
    TO_CHAR(ORDDATE, 'YYYY-MM-DD HH24') 시간,
    SUM(ORDCNT) 주문수량
FROM ORDER1 
GROUP BY (TO_CHAR(ORDDATE, 'YYYY-MM-DD HH24'));

-- 고객별 주문 수량, 주문 금액 합계
SELECT ORDER1.ORDID, SUM(ORDCNT), SUM(ITEMPRICE*ORDCNT)
FROM ITEM1, ORDER1 WHERE ITEM1.ITEMNO = ORDER1.ORDITEM GROUP BY(ORDID);

SELECT * FROM MEMBER1 M1, (
    SELECT ORDER1.ORDID, SUM(ORDCNT), SUM(ITEMPRICE*ORDCNT)
    FROM ITEM1, ORDER1 WHERE ITEM1.ITEMNO = ORDER1.ORDITEM 
    GROUP BY(ORDID)) T1 
WHERE M1.USERID = T1.ORDID;
    
SELECT * FROM ITEM1;
SELECT * FROM ORDER1;

-- 주문 수량이 30개 미만인 주문내역의 개수
SELECT * FROM ORDER1, ITEM1 WHERE ORDER1.ORDITEM=ITEM1.ITEMNO AND ORDER1.ORDCNT<30;

-- 지역별 주문 수량 합계
SELECT MEMBER1.USERADDR 지역, SUM(ORDER1.ORDCNT) 주문수량합계 
FROM ORDER1, MEMBER1 WHERE ORDER1.ORDID = MEMBER1.USERID GROUP BY(MEMBER1.USERADDR);

좋은 웹페이지 즐겨찾기