728x90

 

JOIN에 AND

SELECT F1.EMP_NO 직원번호, F1.FAM_NM 쌍둥이1, F2.FAM_NM 쌍둥이2, 'Y' "쌍둥이 여부"
FROM FAM_C F1
    JOIN FAM_C F2 ON(F1.EMP_NO = F2. EMP_NO)
AND F1.FAM_NM <> F2.FAM_NM
AND F1.REL_TYPE_CD = 'A27'
AND F1.REL_TYPE_CD = F2.REL_TYPE_CD
AND F1.BIRTH_YMD = F2.BIRTH_YMD
;

 

JOIN + WHERE절에 AND

SELECT F1.EMP_NO 직원번호, F1.FAM_NM 쌍둥이1, F2.FAM_NM 쌍둥이2, 'Y' "쌍둥이 여부"
FROM FAM_C F1
    JOIN FAM_C F2 ON(F1.EMP_NO = F2. EMP_NO)
WHERE F1.FAM_NM <> F2.FAM_NM
AND F1.REL_TYPE_CD = 'A27'
AND F1.REL_TYPE_CD = F2.REL_TYPE_CD
AND F1.BIRTH_YMD = F2.BIRTH_YMD    
;

 

위 둘의 차이는 뭘까?

 

JOIN에 AND 조회 결과

 

JOIN + WHERE절에 AND

 

조회 결과 행(ROW) 수도 같고 직원번호를 하나씩 따져봐도 같다

 

그럼 차이가 없는 걸까?

답은 NO

 

현재는 내부조인(INNER JOIN)이라 차이가 없지만 외부조인(OUTER JOIN)으로 들어가면 달라지게 된다.

FROM절에서 조건을 걸어서 이미 조건대로 걸러지는 것과

FROM절의 데이터를 토대로 WHERE에서 조건을 거는 것의 차이

쿼리의 작동 순서가 FROM절 WHERE절 순이기 때문

 

<쿼리 동작 순서>

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY

 

 

728x90
반응형
728x90

 

배열(Array)

자바스크립트에서는 자료형 지정이 없기 때문에 한 배열 안에 모든 자료형 보관 가능

 

1.배열 선언 및 초기화

배열 선언 시 크기를 지정하지 않고 선언할 수도 있고 크기를 정하고 선언할 수도 있음

function arrayTest2(){
  var arr1 = new Array();     // 배열 선언
  var arr2 = new Array(3);    // 배열 및 배열 길이 선언
  console.log('arr1.length : ' + arr1.length);
  console.log('arr2.length : ' + arr2.length);

  // length가 0이면 값 삽입 불가능? 확인 ㄱ
  

  // 배열 추가
  arr1[0] = '사과';
  arr1[1] = '귤';
  arr1[2] = '바나나';
  arr1[3] = '딸기';       // 4번째 인덱스에 추가됨. 
  // 배열 길이 0으로 지정해놔도 데이터 계속 들어갈 수 있음

  console.log('arr1.length : ' + arr1.length);
  console.log(arr1);

  // 알아서 값이 증가하면서 값도 받아옴
  arr2[0] = '지하철';
  arr2[1] = '기차';
  arr2[2] = '비행기';

  console.log('arr2.length : ' + arr2.length);
  console.log(arr2);
  

  // 초기화 의미 : 객체 선언을 하고 값을 최초로 할당하는 것

  // 선언과 동시에 초기화 방법1 -  강의시간 12:20
  var arr3 = new Array('빨강', '초록', '파랑');
  console.log('arr3.length : ' + arr3.length);
  console.log(arr3);

  // 선언과 동시에 초기화 방법2
  var arr4 = ['java','oracle','jdbc','html','css','javascript'];
  console.log('arr4.length : ' + arr4.length);
  console.log(arr4);  // ['java','oracle','jdbc','html','css','javascript']
}

 

2.배열 메소드

 

indexOf()

해당 요소가 위치한 인덱스 번호 반환

없으면 -1반환

function methodTest1(){
    var arr = ['사과', '포도', '배', '바나나', '감', '키위', '복숭아'];
    console.log(arr.indexOf('바나나'));    // 3. 해당 요소가 위치한 인덱스 반환
    console.log(arr.indexOf('토마토'));    // 배열에 존재하지 않는 값이기에 -1 반환
}

 

concat()

이어 붙이기

function methodTest2(){
    var arrl = ['빨강', '노랑', '초록'];
    var arr2 = ['파랑', '보라'];

    console.log(arr1.concat(arr2)); // ['빨강', '노랑', '초록',//'파랑', '보라']
    console.log(arr2.concat(arr1)); // ['파랑', '보라',//'빨강', '노랑', '초록']
    
    // 메소드 체인 가능
    onsole.log(arr2.concat(arr1).concat(arr1).concat(arr2));
}

 

join()

결합해서 ‘문자열’로 반환

join()은 parameter 지정안하면 ,으로

지정하면 지정한 값(구분자)을 넣어서 구분하여 반환

  • 밑에 toString()과 비슷
<button onclick="methodTest3();">배열 메소드 : join()</button>
<script>
    function methodTest3(){
        var arr = ['강남', '역삼', '선릉', '교대'];
        console.log(arr.join());    // 강남,역삼,선릉,교대
        console.log(typeof arr.join()); // string

    }
</script>

 

reverse()

배열의 값을 뒤집어서 반환

function methodTest4(){
  var arr = [1, 2, 3, 4, 5, 6, 7];
  console.log(arr.reverse());     // [7, 6, 5, 4, 3, 2, 1]
  var arr2 = ['a','b','c','d','e'];
  console.log(arr2.reverse());    // ['e', 'd', 'c', 'b', 'a']
}

 

sort()

배열 값을 정렬 : 안에 들어온 값들을 문자열로 변환해서 문자열 정렬

간단한 문자열 숫자는 숫자로 변환하여 숫자 정렬하고 다음 영어 정렬한다

function methodTest5(){
    var arr = [10, 543, 34, 450, 123, 885];
    console.log(arr.sort());    // [10, 123, 34, 450, 543, 885]

    var arr = ['b', 10, 543, 34, 450, 123, 'a']; 
    console.log(arr.sort());    // [10, 123, 34, 450, 543, 'a', 'b']

		// console.log(a.sort());    //  ['4', 5, 'a', 'b', 'c']    str4를 숫자4로 바꾸고 4,5..순으로 정렬

    // 숫자로 정렬하고 싶을 때 방법
    var sortArr = arr.sort(function(left, right){
                    return left-right; // 내림차순
                    return right-left; // 오름차순
                // 뺄셈을 이용해 누가 더 큰지 알아내고 이를 기반으로   자리를 바꿀지 말지 정한다.
// 레프트 라이트
// 양수 왼쪽값이 더 큼 왼쪽값이 더 크면 안되니 ... 뺄셈을 이용해서 누가 더 큰지 비교
// 자동으로 큰수를 넣는거 그 이후                    
        }
    );
    console.log(sortArr);
}

 

push() & pop()

 - push : 마지막에 요소 추가 <-> unshift // 길이 반환

 - pop : 마지막 요소 꺼내오기 <-> shift // 제거된 요소 반환

       (꺼내오며 마지막 요소가 배열에서 삭제됨)

function methodTest6(){
  var arr = ['김고은', '한예슬', '신민아', '전지현', '손예진', '김소연'];
  arr.push('유인나'); // 마지막에 유인나 추가됨
  console.log(arr);   // ['김고은', '한예슬', '신민아', '전지현', '손예진', '김소연', '유인나']

  arr.push('송혜교'); 
  console.log(arr);   // ['김고은', '한예슬', '신민아', '전지현', '손예진', '김소연', '유인나', '송혜교']

  console.log(arr.push('유인나')); // 9 : 푸쉬가 되고 난 다음에 사이즈가 나오는것

  arr.sort();

  console.log(arr);
  console.log("========")
  console.log(arr.pop()); // 마지막 요소 꺼내오기(꺼내오며 마지막 요소가 배열에서 삭제됨)
  console.log(arr);   
  arr.pop();              // 마지막 요소 꺼내오기(꺼내오며 마지막 요소가 배열에서 삭제됨)
  console.log(arr);
}
// push : 마지막 요소에 추가
console.log(a);           // (5) ['4', 5, 'a', 'b', 'c']
console.log(a.push());    //  5     <- 콘솔에서는 소트된 상태에서 원래 배열의 마지막값 5를 반환
console.log(a.push(6));   //  6    
console.log(a);           // (6) ['4', 5, 'a', 'b', 'c',6]
console.log(a.push())       // 6 // 파라미터 안적으면 배열의 길이 반환(?)
console.log(typeof(a.push()));    //  number

 

shift() & unshift()

 - shift : 첫번째 요소 제거하고, 제거된 요소를 반환 <-> pop // 제거된 요소 반환(str 반환)

 - unshift : 맨 앞에 요소 추가하고, 추가한 길이를 반환 <-> push // 길이 반환(number 반환)

(method) Array<string>.shift(): string

(method) Array<string>.unshift(...items: string[]): number

function methodTest7(){
    var arr = ['야구', '축구', '농구', '배구', '탁구'];
    console.log(arr);         // ['야구', '축구', '농구', '배구', '탁구']

    arr.shift();              // 야구 삭제
    console.log(arr);         // ['축구', '농구', '배구', '탁구']
    console.log(arr.shift()); // 축구
    console.log(arr);         // ['농구', '배구', '탁구']

    arr.unshift('ㅁ');          // ㅁ 추가
    console.log(arr.unshift()); // 4    길이 반환
    console.log(arr);           //  ['ㅁ', '농구', '배구', '탁구']
}

 

slice() & splice()

slice()

slice(start idx, end idx) 끝 인덱스 미포함(-1)해서 엘리먼트 추출

splice()

splice(start idx, end idx, 대체할 idx) a부터 b개까지 c의 값으로 변경

function methodTest8(){
    var arr = ['자바', '오라클', 'JDBC', 'HTML', 'css', 'JavaScript']; // 끝 인덱스 미포함해서
    console.log(arr.slice(2, 4));   // ['JDBC', 'HTML']
    console.log(arr);               // ['자바', '오라클', 'JDBC', 'HTML', 'css', 'JavaScript']
    
    console.log(arr.splice(0, 2, 'Spring')); // ['자바', '오라클'] // 0부터 2개 빼내고 spring을 추가하겠다는 코드
    console.log(arr);       // ['Spring', 'JDBC', 'HTML', 'css', 'JavaScript']

}

 

toString()

join()과 비슷

차이는

toString() : 무조건 ','로 구분지어 반환

join()은 parameter 디폴트는 ',' 들어가고 지정하면 지정한 값(구분자)을 넣어서 각 값을 연결하여 반환

toString() → 무조건 ,쉼표 구분자로 합쳐서 문자열로 연결되어 나옵니다 ≒ join

function methodTest9(){
  var arr = ['잠은', '보약이다', '잠은', '죽어서 자는게', '아니다', '그건', '죽은거다'];
  console.log(arr.toString()); // 잠은,보약이다,잠은,죽어서 자는게,아니다,그건,죽은거다
  console.log(arr.toString('ㅁ'));
  console.log(arr);            // ['잠은', '보약이다', '잠은', '죽어서 자는게', '아니다', '그건', '죽은거다']

  console.log(arr.join());     // 잠은,보약이다,잠은,죽어서 자는게,아니다,그건,죽은거다
  console.log(arr.join('/'));  // 잠은/보약이다/잠은/죽어서 자는게/아니다/그건/죽은거다

  console.log(arr); 

}

 

728x90
반응형
728x90

 

 

2중 조인 + 인라인뷰 서브쿼리 + RNUM 사용

테이블 조회 해보았다

RNUM의 별칭(alias)를 적용하기 위해서는 안쪽 셀렉트문에서 별칭이 선언되어야 밖의 쿼리에서 별칭이 적용될 수 있으니 유의!

 

SELECT * 
FROM BOARD B
    JOIN FOOD F ON(B.FOOD_NO = F.FOOD_NO)
    JOIN RESTAURANT R ON(B.RESTAURANT_NO = R.RESTAURANT_NO)
WHERE B.STATUS = 'Y' AND BOARD_TYPE = 1;



SELECT *
FROM (SELECT ROWNUM RNUM, DESCBOARD.*
      FROM (SELECT * 
            FROM BOARD B
                JOIN FOOD F ON(B.FOOD_NO = F.FOOD_NO)
                JOIN RESTAURANT R ON(B.RESTAURANT_NO = R.RESTAURANT_NO)
                WHERE B.STATUS = 'Y' AND BOARD_TYPE = 1) DESCBOARD)
WHERE RNUM >=2 AND RNUM
728x90
반응형
728x90

 

 

사용 프로그램

Oracle 11g

 

메세지

ORA-25154: column part of USING clause cannot have qualifier 25154. 00000 - "column part of USING clause cannot have qualifier"

*Cause: Columns that are used for a named-join (either a NATURAL join or a join with a USING clause) cannot have an explicit qualifier.

*Action: Remove the qualifier.

 

상황

ANSI 표준구문으로 사번, 사원 명, 직급코드, 직급명 조회할려던 중 발생

 

원인

ANSI 표준구문에서 USING 자체가 다른 테이블에 같은 컬럼명을 JOIN한다는 전제가 깔려있기에 SELECT절에 JOIN되는 각 컬럼 앞에 테이블 경로 지정해줄 필요가 없다

 

해결

식별자(quilifier) 삭제

 

-- 에러 해결 전
EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE E
    JOIN JOB J USING(JOB_CODE);
    
 -- 에러 해결 후
 EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
    JOIN JOB USING(JOB_CODE);
728x90
반응형
728x90

 

SELECT, FUCTION,  GROUP BY, HAVING, JOIN 100제 문제 풀이

100제 중 87문제 풀이 완료

 




--SELECT 문제
--1. EMPLOYEE 테이블의    사번, 이름, 급여   조회
SELECT EMP_NO, EMP_NAME,SALARY
FROM EMPLOYEE;
--2. EMPLOYEE 테이블의    모든    정보    조회
SELECT * FROM EMPLOYEE;
--3. JOB 테이블의   모든    정보   조회
SELECT * FROM JOB;
--4. JOB 테이블의   직급    이름   조회
SELECT JOB_NAME FROM JOB;
--5. DEPARTMENT 테이블의    모든    정보    조회
--6. EMPLOYEE 테이블의    직원    명, 이메일, 전화번호, 고용일    조회
--7. EMPLOYEE 테이블의    고용일, 사원    이름, 월급    조회
--8. EMPLOYEE 테이블에서    직원    명, 급여, 연봉    조회(연봉    = 급여*12)
SELECT EMP_NAME,SALARY,SALARY*12
FROM EMPLOYEE;
--9. EMPLOYEE 테이블에서    직원    명, 연봉, 보너스를    추가한    연봉    조회
SELECT EMP_NAME,SALARY,SALARY*12
FROM EMPLOYEE;
--10.EMPLOYEE  테이블에서      이름,  연봉,  총수령액(보너스      포함),  실수령액(총수령액-(연봉*세금 3%)) 조회
SELECT EMP_NAME 이름,SALARY 급여,SALARY*12-(SALARY*12*0.03) 총수령액, SALARY*12 연봉
FROM EMPLOYEE;
--11.EMPLOYEE  테이블에서      이름,  고용일,  근무일수(오늘      날짜      -  고용일)  조회,  오늘      날짜: SYSDATE
SELECT EMP_NAME, HIRE_DATE, SYSDATE - HIRE_DATE 근무일수, SYSDATE 오늘
FROM EMPLOYEE;
--12.EMPLOYEE 테이블에서    직원의    직원    번호, 사원    명, 급여, 단위    조회
--13.EMPLOYEE 테이블에서    직원의    직급    코드    조회
--14.EMPLOYEE 테이블에서    직원의    직급    코드를    중복    없이    조회
SELECT DISTINCT JOB_CODE
FROM EMPLOYEE;
--15.EMPLOYEE 테이블에서    직원의    부서    코드를    중복    없이    조회
SELECT DISTINCT DEPT_CODE
FROM EMPLOYEE;
--16.EMPLOYEE 테이블에서    부서    코드가    'D9'인    직원의    이름, 부서    코드    조회
SELECT EMP_NAME,DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE = 'D9';
--17.EMPLOYEE 테이블에서    급여가    4000000 이상인    직원의    이름, 급여    조회
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY >= 4000000;
--18.EMPLOYEE 테이블에서    부서    코드가    ‘D9’가    아닌    사원의    사번, 이름, 부서    코드    조회
SELECT EMP_ID, EMP_NAME,DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE != 'D9';
--19.EMPLOYEE  테이블에서    퇴사    여부가    N인    직원을    조회하고    근무    여부를    재직중으로    표시하 고    사번, 이름, 고용일, 근무    여부    조회
SELECT EMP_ID, EMP_NAME, HIRE_DATE, ENT_YN 재직중
FROM EMPLOYEE
WHERE ENT_YN = 'N' ;
--20.EMPLOYEE 테이블에서    월급이    3000000이상인    사원의    이름, 월급, 고용일    조회
--21.EMPLOYEE 테이블에서    SAL_LEVEL이   ‘S1’인    사원의    이름, 월급, 고용일, 연락처    조회
--
--22.EMPLOYEE 테이블에서    실수령액(총수령액    - (연봉*세금%3))이    5천만원    이상인    사원의    이름, 급여, 실수령액, 고용일    조회
--23.EMPLOYEE  테이블에서    부서    코드가    ‘D6’이고    급여를    3000000보다    많이    받는    직원의    이름, 부서    코드, 급여    조회
--24.EMPLOYEE  테이블에서    부서    코드가    ‘D6’이거나    급여를    3000000보다    많이    받는    직원의    이 름, 부서   코드, 급여    조회
--25.EMPLOYEE  테이블에서    급여를    3500000  이상    6000000  이하를    받는    사원의    사번,  이름,  급 여, 부서코드, 직급코드
--26.EMPLOYEE테이블에    월급이    4000000이상이고    JOB_CODE가    ‘J2’인    사원의    전체    내용    조회
--27.EMPLOYEE 테이블에    DEPT_CODE가    ‘D9’이거나    ‘D5’인    사원    중에    고용일이    02년    1월    1일보 다    빠른   사원의    이름, 부서코드, 고용일   조회
--28.EMPLOYEE  테이블에서    급여를    3500000  미만    6000000  초과를    받는    사원의    사번, 이름,  급 여, 부서코드, 직급코드
--29. EMPLOYEE 테이블에    고용일이    90/01/01 ~ 01/01/01인    사원의    전체    내용을    조회
SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE >= '90/01/01' AND HIRE_DATE <= '01/01/01';
--30. EMPLOYEE 테이블에서    성이    ‘전’씨인    사원의    사번, 고용일    조회
--31. EMPLOYEE 테이블에서    이름이    '하'가    포함된    직원의    이름, 주민번호, 부서코드    조회
--32. EMPLOYEE 테이블에서    전화번호    4번째    자리가    9로    시작하는    사원의    사번, 이름, 전화번호 조회
--33. EMPLOYEE  테이블에서    이메일    중    _의    앞    글자가    3자리인    이메일    주소를    가진    사원의    사 번, 이름, 이메일    주소    조회
SELECT EMP_ID,EMP_NAME, EMAIL
FROM EMPLOYEE
WHERE EMAIL LIKE '___!_%' ESCAPE '!';
--34. EMPLOYEE 테이블에서    이름    중    김씨    성을    가지지    않은    사원의    사번, 이름, 고용일   조회
--35. EMPLOYEE 테이블에서    이름    끝이    '연'으로    끝나는    사원    조회
SELECT *
FROM EMPLOYEE
WHERE EMP_NAME LIKE '%연';
--36. EMPLOYEE 테이블에서    전화번호    처음    세자리가    010이    아닌    사원의    이름, 전화번호    조회
SELECT EMP_NAME,PHONE
FROM EMPLOYEE
WHERE PHONE NOT LIKE '010%';
SELECT EMP_NAME,PHONE
FROM EMPLOYEE
WHERE NOT PHONE LIKE '010%';
--37. EMPLOYEE  테이블에서     메일주소     _의     앞이     4자이면서     DEPT_CODE가     ‘D9’     또는     ‘D6’이고, 
-- 고용일이    90/01/01 ~ 00/12/01이고, 급여가   2700000만    이상인    사원의    전체    정보    조회
SELECT *
FROM EMPLOYEE
WHERE EMAIL LIKE '____!_%' ESCAPE '!'
        AND (DEPT_CODE = 'D9' OR DEPT_CODE = 'D6')
        AND HIRE_DATE BETWEEN '90/01/01' AND '00/12/01'
        AND SALARY >= 2700000;
        
--38. EMPLOYEE 테이블에서    보너스를    받지    않는    사원의    사번, 이름, 급여, 보너스    조회
SELECT EMP_ID, EMP_NAME, SALARY,  NVL(BONUS, 0)---------------------
FROM EMPLOYEE
WHERE BONUS = 0;
--39. EMPLOYEE 테이블에서    보너스를    받는    사원의    사번, 이름, 급여, 보너스    조회
SELECT EMP_ID, EMP_NAME, SALARY, BONUS
FROM EMPLOYEE
WHERE BONUS IS NULL;
--40. EMPLOYEE  테이블에서 관리자도 없고 부서 배치도 받지 않은 직원의 이름,  관리자,  부서코드    조회
SELECT EMP_NAME, MANAGER_ID, DEPT_CODE
FROM EMPLOYEE
WHERE MANAGER_ID IS NULL AND DEPT_CODE IS NULL;

--41. EMPLOYEE  테이블에서    부서    배치를    받지    않았지만    보너스를    지급받는    직원의    이름,  보너 스, 부서코드   조회
SELECT EMP_NAME,BONUS,DEPT_CODE
FROM EMPLOYEE
WHERE DEPT_CODE IS NULL AND BONUS IS NOT NULL;
--42. ‘D6’부서와   ‘D9’부서원들의    이름, 부서코드, 급여    조회
--43. 직급   코드가   ‘J1’, ‘J2’, ‘J3’, ‘J4’인    사람들의    이름, 직급    코드, 급여    조회
SELECT EMP_NAME, JOB_CODE,SALARY
FROM EMPLOYEE
WHERE JOB_CODE IN ('J1','J2','J3','J4');
--44. EMPLOYEE 테이블에서    사번, 이름, 급여를    연결해서    조회    (EX. 200선동일8000000)
SELECT EMP_ID||EMP_NAME||SALARY
FROM EMPLOYEE;
--45. EMPLOYEE 테이블에서    '사원    명의    월급은    급여    원입니다' 형식으로    조회
SELECT '사원명 '||EMP_NAME||'의 월급은 급여 '|| SALARY||'원입니다'
FROM EMPLOYEE;
--
--
--
--FUNCTION 문제
--1. EMPLOYEE  테이블에서    사원    명,  입사일-오늘,  오늘-입사일    조회    (단,  별칭은    근무일수1,  근 무일수2로   하고    모두    정수    처리(내림)와    양수로    처리)
SELECT EMP_NAME, FLOOR(ABS(HIRE_DATE - SYSDATE)) 근무일수1 , FLOOR(ABS(SYSDATE - HIRE_DATE)) 근무일수2
FROM EMPLOYEE;
--2. EMPLOYEE 테이블에서    사번이    홀수인    직원들의    정보    모두    조회
SELECT *
FROM EMPLOYEE
--WHERE MOD(EMP_ID,2) = 1;
WHERE MOD(EMP_ID,2) != 0;
--3. EMPLOYEE 테이블에서    근무연수가    20년    이상인    직원    정보    조회
SELECT *
FROM EMPLOYEE
WHERE MONTHS_BETWEEN(SYSDATE, HIRE_DATE) >= 20;
--4. EMPLOYEE 테이블에서    사원    명, 입사일, 입사한    달의    근무일    수    조회
SELECT EMP_NAME, HIRE_DATE, LAST_DAY(HIRE_DATE)-HIRE_DATE "입사한 달의 근무일수"
FROM EMPLOYEE;
--5. EMPLOYEE 테이블에서    사원의    이름, 입사    연도, 입사    월, 입사일    조회
SELECT EMP_NAME, HIRE_DATE, LAST_DAY(HIRE_DATE)-HIRE_DATE "입사한 달의 근무일수"
FROM EMPLOYEE;
--6. EMPLOYEE테이블에서    사원의    이름,  입사일,  근무연수    조회    (단,  근무연수는    현재    연도    - 입 사연도로    조회)
SELECT EMP_NAME, HIRE_DATE, EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM HIRE_DATE) 근무연수
FROM EMPLOYEE;
--7. EMPLOYEE 테이블에서    사원    명, 급여(\9,000,000 형식) 조회
SELECT EMP_NAME ,TO_CHAR(SALARY,'L9,000,000') 급여
FROM EMPLOYEE;
--8. EMPLOYEE 테이블에서    이름, 입사일(2022년    3월    15일    (화) 형식) 조회
SELECT EMP_NAME,TO_CHAR(HIRE_DATE, 'YYYY"년" FMMM"월" DD"일" (DY)')
FROM EMPLOYEE;
--9. 직원의 급여를 인상하고자 한다. 직급코드가 ‘J7’인 직원은 급여의 10%를 인상하고, 직급코 드가 ‘J6’인 직원은 급여의 15%를 인상하고, 
-- 직급코드가 ‘J5’인 직원은 급여의 20%를 인상 하며, 그 외 직급의 직원은 급여의 5%만 인상하며, 직원 테이블에서 직원명,  직급코드,  급 여, 인상급여(위 조건)을 조회
SELECT EMP_NAME, JOB_CODE, SALARY, 
        CASE JOB_CODE WHEN 'J7' THEN SALARY*0.1
                      WHEN 'J6' THEN SALARY*0.15
                      WHEN 'J5' THEN SALARY*0.2
                      ELSE SALARY*0.05
        END 인상급여
FROM EMPLOYEE;
SELECT EMP_NAME, JOB_CODE, SALARY, 
    CASE WHEN JOB_CODE = 'J7' THEN SALARY*1.1
         WHEN JOB_CODE = 'J6' THEN SALARY*1.15
         WHEN JOB_CODE = 'J5' THEN SALARY*1.2
         ELSE SALARY*1.05
    END 인상급여
FROM EMPLOYEE;

SELECT EMP_NAME, JOB_CODE, SALARY 월급, 
        DECODE(JOB_CODE,'J7',SALARY*0.1,
                        'J6',SALARY*0.15,
                        'J5',SALARY*0.2,SALARY*0.5) 인상급여
FROM EMPLOYEE;

                        
--10. EMPLOYEE 테이블에서    전    사원의    급여    총합    조회
SELECT SUM(SALARY) FROM EMPLOYEE;
--11. EMPLOYEE 테이블에서    남자사원의    급여    총합    조회
SELECT SUM(SALARY)
FROM EMPLOYEE
WHERE SUBSTR(EMP_NO,8,1)=1;
--12. EMPLOYEE 테이블에서    전    사원의    급여    평균    조회
SELECT AVG(SALARY)
FROM EMPLOYEE;
--13. EMPLOYEE 테이블에서 전 사원의 보너스 평균 (단, BONUS가 NULL인 사원은 0으로 처리)
SELECT AVG(NVL(BONUS,0))
FROM EMPLOYEE;
--14. EMPLOYEE 테이블에서    최소    급여와    최대    급여    조회
SELECT MIN(SALARY), MAX(SALARY)
FROM EMPLOYEE;
--15. 부서   코드가   있는    사원    수    (NULL 제외) 조회
SELECT COUNT(DEPT_CODE)
FROM EMPLOYEE;
SELECT COUNT(DEPT_CODE)
FROM EMPLOYEE;




--GROUP BY HAVING 문제
--1. 부서    별   급여    합계    조회
SELECT SUM(SALARY) 급여합계, DEPT_CODE
FROM EMPLOYEE
GROUP BY DEPT_CODE;
--2. EMPLOYEE 테이블에서 부서, 부서 별 급여 합계, 부서 별 급여 평균, 부서 별 인원 수 조회
SELECT DEPT_CODE 부서코드, SUM(SALARY)급여합계,/*AVG(SALARY)*/ CEIL(AVG(SALARY))급여평균, COUNT(*) 부서인원수
FROM EMPLOYEE
GROUP BY DEPT_CODE;
--3. EMPLOYEE 테이블에서    부서코드와    보너스    받는    사원    수    조회
SELECT DEPT_CODE, COUNT(BONUS) "보너스O사원수"
FROM EMPLOYEE
GROUP BY DEPT_CODE;
--4. EMPLOYEE 테이블에서    직급코드와    보너스    받는    사원    수    조회
SELECT JOB_CODE, COUNT(BONUS) "보너스 사원수"
FROM EMPLOYEE
GROUP BY JOB_CODE;
--5. EMPLOYEE 테이블에서    성별과    성별    별    급여    평균(정수처리(내림)), 급여    합계, 인원    수    조회 (인원    수로   내림차순)
SELECT DECODE(SUBSTR(EMP_NO,8,1),1,'남','여') 성별, FLOOR(ABS(AVG(SALARY))) "성별 별 급여평균", SUM(SALARY), COUNT(*)
FROM EMPLOYEE 
GROUP BY SUBSTR(EMP_NO,8,1)
ORDER BY COUNT(*) DESC;
--6. EMPLOYEE 테이블에서    부서    코드별로    같은    직급인    사원의    급여    합계    조회
SELECT DEPT_CODE, SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING DEPT_CODE IN('D1','D2','D3','D4','D5');

SELECT DEPT_CODE, JOB_CODE, SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE, JOB_CODE
ORDER BY DEPT_CODE;
--7. 부서    코드와   급여    3000000이상인    직원의    그룹    별    평균    급여    조회
SELECT DEPT_CODE, AVG(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE, SALARY
HAVING SALARY >= 3000000;
--8. 부서    코드와   급여    평균    3000000이상인    그룹   별    평균    급여    조회
SELECT  DEPT_CODE, AVG(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE,SALARY
HAVING AVG(SALARY) >= 3000000;
--9. 부서 별 급여 합계 중 9000000을 초과하는 부서코드와 급여 합계 조회
SELECT DEPT_CODE,SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING SUM(SALARY) > 9000000;
--10.EMPLOYEE테이블에서 각 부서코드마다 직급코드 별 급여 합, 부서 별 급여 합, 총합 조회
SELECT DEPT_CODE,JOB_CODE, SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE, JOB_CODE 
ORDER BY DEPT_CODE;
--11. EMPLOYEE  테이블에서 DEPT_CODE가 ‘D5’이거나 급여가 3000000을 초과하는 직원의 사번, 이름, 부서코드, 급여 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE, SALARY
FROM EMPLOYEE
WHERE DEPT_CODE = 'D5' OR SALARY > 3000000;

--
--JOIN 문제
--내부 조인(INNER JOIN) : 일치하지 않는 컬럼 값은 제외시킴 
--1. 사번, 사원 명, 부서코드 조회
SELECT EMP_ID, EMP_NAME, DEPT_CODE FROM EMPLOYEE;
--2-1.사번, 이름,부서코드, 부서 명 조회(오라클 전용 구문) 
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID;
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID;
--2-2.사번, 이름,부서코드, 부서 명 조회(ANSI 표준 구문)
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON(EMPLOYEE.DEPT_CODE = DEPARTMENT.DEPT_ID);
--3-1.사번, 사원 명, 직급코드, 직급명 조회(오라클 전용구문) 
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE = J.JOB_CODE;

SELECT EMP_ID,EMP_NAME, EMPLOYEE.JOB_CODE, JOB.JOB_NAME
FROM EMPLOYEE, JOB
WHERE EMPLOYEE.JOB_CODE = JOB.JOB_CODE;
--3-2.사번, 사원 명, 직급코드, 직급명 조회(ANSI 표준구문) 
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE E
    JOIN JOB J USING(JOB_CODE);
    
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE E
    JOIN JOB J ON(E.JOB_CODE = J.JOB_CODE);
--4-1.부서   명과   해당    부서의    지역    명    조회(오라클    전용    구문)
SELECT D.DEPT_TITLE, L.LOCAL_NAME
FROM DEPARTMENT D, LOCATION L
WHERE D.LOCATION_ID = L.LOCAL_CODE;

SELECT DEPT_TITLE,LOCAL_NAME
FROM DEPARTMENT, LOCATION
WHERE LOCATION_ID = LOCAL_CODE;
--4-2.    부서   명과   해당    부서의    지역    명    조회(ANSI 표준    구문)
SELECT DEPT_TITLE, LOCAL_NAME
FROM DEPARTMENT D
    JOIN LOCATION L ON(D.LOCATION_ID = L.LOCAL_CODE);
--5. 오라클    전용    구문    ANSI 표준    구문으로    바꾸기
--SELECT EMP_NAME, DEPT_TITLE FROM EMPLOYEE, DEPARTMENT WHERE DEPT_CODE = DEPT_ID(+);
SELECT EMP_NAME, DEPT_TITLE 
FROM EMPLOYEE E
    LEFT JOIN DEPARTMENT D ON (E.DEPT_CODE = D.DEPT_ID);
SELECT EMP_NAME, DEPT_TITLE 
FROM EMPLOYEE
    LEFT OUTER JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);    
--6. 오라클    전용    구문    ANSI 표준    구문으로    바꾸기
--SELECT EMP_NAME, DEPT_TITLE FROM EMPLOYEE, DEPARTMENT WHERE DEPT_CODE(+) = DEPT_ID;
SELECT EMP_NAME, DEPT_TITLE 
FROM EMPLOYEE
    RIGHT OUTER JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
--7. 오라클    전용    구문에선    FULL [OUTER] JOIN 안    됨. 아래    구문    실행해도    에러    남. 그러니까 밑에    구문을    ANSI 표준으로    바꿔주셈.
--SELECT EMP_NAME, DEPT_TITLE FROM EMPLOYEE, DEPARTMENT WHERE DEPT_CODE(+) = DEPT_ID(+);
SELECT EMP_NAME, DEPT_TITLE 
FROM EMPLOYEE
    FULL OUTER JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
--8-1.   사번, 이름, 부서    코드, 부서    명, 지역    이름(LOCAL_NAME) 조회(오라클    전용    구문) 
SELECT EMP_ID,EMP_NAME, DEPT_CODE, DEPT_TITLE,LOCAL_NAME
FROM EMPLOYEE, DEPARTMENT,LOCATION
WHERE DEPT_CODE = DEPT_ID
    AND LOCATION_ID = LOCAL_CODE;
--8-2.   사번, 이름, 부서    코드, 부서    명, 지역    이름(LOCAL_NAME)(ANSI 표준    구문)
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE, LOCAL_NAME
FROM EMPLOYEE
    JOIN DEPARTMENT ON ( DEPT_CODE = DEPT_ID)
    JOIN LOCATION ON ( LOCATION_ID = LOCAL_CODE);



--SUBQUERY 문제
--서브    쿼리(SUBQUERY) :  메인    쿼리를    위해    보조    역할을    하는    쿼리이며,  쿼리    안에    쿼리가    포 함되어   있음.
--1. 첫    번째   구문과    두    번째    구문    합쳐주셈.
--①
--SELECT DEPT_CODE FROM EMPLOYEE
--WHERE EMP_NAME = '노옹철';
--②
--
--SELECT EMP_NAME FROM EMPLOYEE
--WHERE DEPT_CODE = 'D9';
--2. 전    직원의   평균    급여보다    많은    급여를   받고    있는    직원의    사번, 이름, 직급    코드, 급여    조회
--3. 노옹철    사원의   급여보다    많이    받는    직원의    사번, 이름, 부서코드, 직급코드, 급여    조회
--4. 가장    적은   급여를    받는    직원의    사번, 이름, 직급코드, 부서코드, 급여    입사일    조회
--5. 부서    별   급여    합계    중    가장    큰    부서의   부서    명, 급여    합계
--6. 부서    별   최고    급여를    받는    직원의    이름, 직급    코드, 부서코드, 급여    조회
--7. 관리자와    일반    직원에    해당하는    사원    정보    추출    : 사번, 이름, 부서명, 직급, 구분(관리자/직 원)
--8. 대리    직급의    직원들    중에서    과장    직급의    최소    급여보다    많이    받는    직원의    사번, 이름, 직급, 급여    조회
--9. 차장    직급의   급여    중    가장    큰    값보다   많이    받는    과장    직급의    사번, 이름, 직급, 급여    조회
--10.퇴사한    여직원과    같은    부서, 같은    직급에    해당하는    사원의    이름, 직급    코드, 부서코드, 입사 일    조회
--11.자기    직급의    평균    급여를    받고    있는    직원의    사번,  이름,  직급    코드,  급여    조회    (단, 급여    평 균은    십   만원    단위로    계산    : TRUNC(컬럼    명, -5))
--12.전    직원   중    급여가    높은    상위    5명의   이름, 급여    조회
--13.전    직원   중    급여가    높은    상위    5명의   이름, 급여    조회

 

 

 

728x90
반응형
728x90

 

JOIN 

INNER JOIN, OUTER JOIN

오라클 전용구문, ANSI 표준구문

-- 04.JOIN ★★★

/*
JOIN이란?
하나 이상의 테이블에서 데이터를 조회하기 위해 사용
여러개의 테이블들을 연결하여 데이터를 조회


<JOIN 세부 종류>
1.내부 조인
데이터가 ‘같은 부분’끼리 연결
위의 특성 때문에 해당하지 않는 데이터는 제외하고 반환됨
    1)오라클 전용구문 
        FROM절에 해당 테이블 모두 기술
        테이블끼리 연결하는 부분은 WHERE을 통해 연결
    2)ANSI 표준구문
        FROM절에 해당되는 테이블 모두 기술
        JOIN 구문 이용 
            JOIN + ON : 두 데이터값이 다른 이름일 때
            JOIN + USING : 두 데이터값이 같은 이름일 때
            but, 이름이 같더라도 JOIN + ON 사용가능

2.외부 조인
데이터가 같지 않은 행도 조인에 포함
내부 조인의 공통 데이터만 추출하는 특성에서 한쪽만 충족하는 데이터를 더 가져 올 수 있게 한 조인
    1)오라클 전용구문
        맞춰주는 테이블(기준이 아닌 테이블)의 컬럼 쪽에 (+)
    2)ANSI 표준구문 : 좀 더 LEFT, RIGHT 직관적
        LEFT OUTER JOIN
        RIGHT OUTER JOIN
        FULL OUTER JOIN : 양쪽 다 기준
        (OUTER)는 생략 가능


*/

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

--1.내부조인(Inner join)
--    1)오라클 전용 구문
--          컬럼명이 같으면 어느 테이블 컬럼인지 지정해줘야함 : 테이블명.컬럼명으로 지정
--    2)ANSI 표준 구문
--          내가 연결할 컬럼의 이름이 다를 때 = ON 사용
--          내가 연결할 컬럼이 이름이 같을 때 = USING 사용
--               컬럼 이름이 같다고 해서 무조건 USING 사용? X  


-- 사번, 이름, 부서코드, 부서명
-- 오라클 전용 구문
SELECT EMP_ID, EMP_NAME, DEPT_ID, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID -- 결과값 21개. 부서코드가 NULL인 직원은 제외
ORDER BY DEPT_ID;         

-- ANSI 표준 구문
SELECT EMP_ID, EMP_NAME, DEPT_ID, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);


-- 사번, 사원명, 직급코드, 직급명 // 각 사원에 대한 직급명 조회
-- 오라클 전용 구문
-- ANSI 표준 구문
-- 풀이과정
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE "E", JOB "J"
WHERE E.JOB_CODE = J.JOB_CODE; -- 23행
-- JOIN ~ ON
SELECT EMP_ID, EMP_NAME, EMPLOYEE.JOB_CODE, JOB_NAME
FROM EMPLOYEE
    JOIN JOB ON(EMPLOYEE.JOB_CODE = JOB.JOB_CODE);
SELECT EMP_ID, EMP_NAME, EMPLOYEE.JOB_CODE, JOB.JOB_NAME
FROM EMPLOYEE
    JOIN JOB ON(EMPLOYEE.JOB_CODE = JOB.JOB_CODE);
-- JOIN ~ USING
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
    JOIN JOB USING(JOB_CODE); 
-- USING 쓰면 FROM EMPLOYEE테이블에 JOB테이블을 조인시키면서 명시되므로,
-- USUNG()안에 JOB.이라고 명시할 필요X
    
-- < ANSI 표준 구문>
-- 내가 연결할 컬럼의 이름이 다를 때 = ON 사용
-- 내가 연결할 컬럼이 이름이 같을 때 = USING 사용
--      컬럼 이름이 같다고 해서 무조건 USING 사용? X  

-- 테이블명 EMPLOYEE에 별칭 사용 연결
-- 오라클 전용구문
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE "E", JOB "J"
WHERE E.JOB_CODE = J.JOB_CODE; -- 23행
-- ANSI 표준 구문
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, J.JOB_NAME
FROM EMPLOYEE "E"
    JOIN JOB "J" ON(E.JOB_CODE = J.JOB_CODE); -- 23행


-- 부서명과 해당 부서의 지역명 조회
-- 오라클 전용 구문
-- ANSI 표준 구문
SELECT D.DEPT_TITLE, L.LOCAL_NAME
FROM DEPARTMENT "D", LOCATION "L"
WHERE D.LOCATION_ID = L.LOCAL_CODE;
-- 오라클 전용 구문
-- 경로지정X & 별칭X
SELECT DEPT_TITLE, LOCAL_NAME
FROM DEPARTMENT, LOCATION
WHERE LOCATION_ID = LOCAL_CODE;  -- 9행 인사관리부	ASIA1
-- ANSI 표준 구문
SELECT DEPT_TITLE, LOCAL_NAME
FROM DEPARTMENT
    JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE); -- 9행 인사관리부	ASIA1


------------------------------------------------------------------------------
------------------------------------------------------------------------------
-----------------------------2.외부조인(Outer join)-----------------------------
------------------------------------------------------------------------------
/*
내부 조인의 한계
매칭이 안되는 값이 있으면 조인해서 가져올 수 없는 한계
-> 보완하는 것이 외부조인
내부조인 개념이 일치하는 것을 가져오는 것

 2.외부조인(Outer join)
 컬럼 값이 일치하지 않는 행도 조인에 포함시킴
 아우터 조인 무조건 명시해야함

종류
1.LEFT (OUTER) JOIN
2.RIGHT (OUTER) JOIN
3.FULL (OUTER) JOIN
    - 오라클 구문은 풀아우터 조인 사용불가
- (OUTER) : 생략가능
    

*/ 

-- INNER JOIN
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); 
    -- 21행 : DEPT_CODE가 NULL인 사람은 제외(매칭X)



SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); -- 21행 : DEPT_CODE가 NULL인 사람은 제외(매칭X)
    

--1.LEFT (OUTER) JOIN
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    LEFT OUTER JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID(+);


-- 내부조인과 차이
-- 내부조인에서는 부서코드가 NULL인 직원은 제외되고 21행 나왔지만
-- LEFT OUTER JOIN은 NULL인 직원 2명도 포함했기에 23행 출력
 
/* 
내 기준으로 왼쪽에 있는 얘를 기준으로 삼겠다
즉 EMPLOYEE가 기준
디파트가 임플한테 맞춰주는 것. 
그래서 오라클 전용구문에서 표기가 기준점이 되는 테이블이 아닌 조이하는 테이블(+) 붙임
ex)WHERE DEPT_CODE = DEPT_ID(+);


<강사쌤 설명>
--레프트 라이트 조인 기준으로 왼쪽이면 임플로이 오른쪽이면 디파트
--레프트는 임플이 기준이라 임플로이 전부를 출력함(23개행). 내부조인 하면 하동운,이오리 안나옴.
--임플이 기준이라 NULL값도 출력을 해줌
--디파트가 임플 맞춰줘야함->23개행이 나올 수 있도록 

<내가 한 이해>
레프트 라이트 조인 기준으로 왼쪽이면 임플로이 오른쪽이면 디파트
임플로이에는 EMP_NAME에서 사원명 가져오는데 이게 23명이고,
디파에서는 DEPT_TITLE에서 부서명 가져오는데 이건 21개. 부서배정이 아직인 2명이
NULL로 나오는데 임플 기준이라 23행 맞춰줘야하니 부서명이 없는 2명은 NULL로 표시

 
Q.EMPLOYEE안에 DEPT_CODE가 있으니까 DEPT_CODE안에 NULL이 있어도 일단 쓰고, 
  DEPARTMENT를 DEPT_CODE에 맞춰서 나온거죠,,?
A.YES

*/


 
 
--2.RIGHT (OUTER) JOIN
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID;

SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    RIGHT OUTER JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);

-- ★양쪽 테이블의 매칭된 데이터 + 가져오길 원하는 한쪽 집합의 데이터★

--3.FULL (OUTER) JOIN
-- 둘 다 기준이 된다
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID(+);
-- ERROR :  a predicate may reference only one outer-joined table
-- 오라클 구문으로는 기준을 하나만 정할 수 있어 풀아우터조인은 사용불가

SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
    FULL OUTER JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID); 
-- 26행 출력 : 
-- LEFT의 부서배정안된 22이오리23하동운 NULL 데이터 + RIGHT의 부서만 있고 직원 없는 
-- (NULL) 해외영업3부,마케팅부,국내영업부해서 
-- 내부조인 결과 21행에 LEFT 2행+ RIGHT 3행 = 21+2+3= 총26행
728x90
반응형

+ Recent posts