jdbc 드라이버 가져오기


1)오라클 설치 폴더에 db_1\jdbc\lib에서 ojdbc14를 복사합니다


2)자바 설치 폴더에 jdk1.7에서 jre\lib\ext에 붙혀 넣습니다 완료!!


참고 이클립스에서 드라이버 넣기

Project - Properties클릭





오라클 드라이버 이용하여 데이터를 주고 받기 위해 사용하는 객체는 3가자 있습니다


1) connection객체 : 오라클 DB와  자바를 연결시켜주는 역할을 합니다

try {

String url = "jdbc:oracle:thin:@localhost:1521:ora10g";

String user = "scott";

String pwd = "erp00500";

Class.forName("oracle.jdbc.driver.OracleDriver");

con = DriverManager.getConnection(url,user,pwd);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e){

e.printStackTrace();

}


2) Statement객체 : 쿼리를 작성할때 ?가 없는 바로 값을 넣을때

    PreparedStatement객체 : 쿼리를 작성할때 ? 로 정해두고 뒤에 값을 넣을때

"insert into friend values(friend_seq.nextval,?,?,?,?)";

try {

ps = con.prepareStatement(sql);

ps.setString(1, f.getName());

ps.setInt(2, f.getAge());

ps.setString(3, f.getAddr());

ps.setString(4, f.getTel());

ps.executeUpdate();

} catch (SQLException e) {

e.printStackTrace();

}


3) ResultSet객체 : 값을 자바로 받아올 값이 있을대

String sql = "select * from friend";


try {

st = con.createStatement();

rs = st.executeQuery(sql);

while(rs.next()){

int num = rs.getInt("num");

String name = rs.getString("name");

int age = rs.getInt("age");

String addr = rs.getString("addr");

String tel = rs.getString("tel");

System.out.println("이름 : " + name + "\t" + "주소 : " + addr);

}

} catch (SQLException e) {

e.printStackTrace();

}



Posted by mantwo

Thread

: 프로세스 내에서 실제 작업을 수행이란 의미


간단하게 예를 들자면 단일 프로세스의 프로그램에서 채팅 프로그램을 구현한다면 대화를 주고 받기가 되질 않습니다 그저 한방향으로 실행되어지고 끝이 날뿐입니다 그래서 나온것이 쓰레드 입니다 하나의 프로세스에서 독립적으로 역활을 수행하는 쓰레드가 존재 함으로 123 123 123의 반복된 결과만 나오는 것이 아니라 111 121 122 321... 등의 다양한 값을 얻을수 있는 다시말하자면 프로세서내의 여러가지 기능을 수행하는 독립적인 다중 쓰레드를 사용함으로서 다양하고 편리한 목적의(멀티) 프로그램을 구현 할수 있습니다


Thread를 사용하는 2가지예

1) 상속 : extends Thread

 -Thread 객체를 선언하여 사용합니다

 -구현은 run()을 이용합니다

 -실행 매소드는 run()이 아닌 start()입니다 


2) 인터페이스 : implement Runnable

 -구현은 run()을 이용합니다

 -start()를 사용하기 위해서는 Thread객체를 사용해야 합니다


기본적인예제1>쓰레드 기본

소스보기 : 3 5 9단이 무작위로 출력되는 구구단을 출력하는 프로그램을 작성합니다 2가지 방법으로 구현 

1)extends

public class ThreadEx01 extends Thread {

private int d;

public ThreadEx01(int d){

this.d = d;

}

public void run(){

for (int i = 1; i < 10; i++) {

System.out.println(d+"*"+i+"="+d*i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

System.out.println();

}

public static void main(String[] args) {

ThreadEx01 th = new ThreadEx01(5);

th.start();

ThreadEx01 th1 = new ThreadEx01(9);

th1.start();

ThreadEx01 th2 = new ThreadEx01(3);

th2.start();

}

}


2)implement

public class ThreadEx02 implements Runnable {

private int d;

public ThreadEx02(int d){

this.d = d;

}

public void run(){

for (int i = 1; i < 10; i++) {

System.out.println(d+"*"+i+"="+d*i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

System.out.println();

}

public static void main(String[] args) {

ThreadEx02 th = new ThreadEx02(5);

Thread t = new Thread(th);

t.start();

ThreadEx02 th1 = new ThreadEx02(9);

Thread t1 = new Thread(th1);

t1.start();

ThreadEx02 th2 = new ThreadEx02(3);

Thread t2 = new Thread(th2);

t2.start();

}

}



기본적인 예제2>쓰레드 충돌

: 기본 적으로 쓰레드를 사용하게 되면 1 2 3 의 독립 적인 3개체가 서로 중복되는 상황이 발생합니다 예를 들어 10000번 수행하는 프로그램의 경우 ++증가를 할경우 3개체가 중복이 되지 않으면 30000이 나와야 정상이지만 29997 28787등의 중복으로 인하여 정상적인 값이 출력이 되지 않습니다


implement로 구현

class Increment{

int num = 0;

public synchronized void increment(){num++;}

public int getNum(){return num;}

}

class IncThread extends Thread{

Increment inc;

public IncThread(Increment inc){

this.inc =inc;

}

public void run(){

for (int i = 0; i < 100; i++) {

for (int j = 0; j < 100; j++) {

inc.increment();

}

}

}

}

public class ThreadSyncError {

public static void main(String[] args) {

Increment inc = new Increment();

IncThread it1 = new IncThread(inc);

IncThread it2 = new IncThread(inc);

IncThread it3 = new IncThread(inc);

it1.start();

it2.start();

it3.start();

try {

it1.join();

it2.join();

it3.join();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(inc.getNum());

}

}


정상적으로 30000이 출력됩니다


추가로 스레드로 구성된 프로그램에서 main문 안의 System.out.println 출력문은  스레드가 어느 위치에서 실행이 되던지 제일 처음 출력이 됩니다 하지만 지금 같은 예제의 경우는 제일 마지막 프로그램 종료 시점에서 출력을 해야됩니다 이러한 경우 try문안에 join을 사용하면 스레드를 모두 실행한후 다음으로 넘어가게 되니다

Posted by mantwo

DB Modeling


개념적 -> 논리적 -> 물리적

         ERD

         ER -win

         sql developer modeler

         visual paradime

         power design

         DA#


요구사항 -> 분석 -> 설계 ->구현 -> 테스트 -> 유지보수

<-          용어사전           ->/기능분해도




entity 논리적

table 물리적






Posted by mantwo


데이터베이스 링크(Database Link)

: 오라클을 사용하다보면 자신의 서버 이외에 테이블이나 자료들을 사용해야 될때가 있습니다 그럴때 링크를 걸어주어 물리적으로는 떨어져있지만 데이터를 사용 할 수 있는 방법이 데이터베이스 링크 입니다


계정확인 하기 enterprise manager console로 접속합니다

create database link를 체크 합니다




developer에서 하단 매뉴중 

데이터베이스 부분에서 우클릭 하여 새데이터베이스 링크 생성을 클릭합니다


비어 있는 서비스 이름은...


오라클이 설치된 계정의 

 D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN

tnsnames.ora를 메모장으로 열면 나오는 부분중 아래의 부분만 드래그 복사합니다



ORA10G = *이 한줄만 빼고 붙혀넣기를 합니다

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = java119)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = ora10g)

    )

  )







참고>링크명 정리하기

처음 Database link를 하게 되면 링크명이 Databas_link_RD......ORACLE.COM 길게 표시됩니다

이것을 간단하게 정리 하는 방법은 아래와 같습니다


sys계정으로 접속하여 아래와 같이 쳐줍니다


select * from props$ where name = 'GLOBAL_DB_NAME';

 

show parameters DB_NAME;

 

update props$ set value$ = 'ora10g' where name = 'GLOBAL_DB_NAME';


Database link 사용방법

테이블명@링크명;  

select * from emp@database_link;



Database link 삭제

 DROP DATABASE LINK DBLINK명;

drop database link database_link;



문제> 링크 테스트중에 에러가 발생하거나 적용이 되지 않는다면 아래의 두 서비스를 다시 시작하여 줍니다!








Posted by mantwo

뷰(view)

뷰(view) 논리적인 가상테이블을 뜻합니다 사용할때만 생성되고 물리적으로는 존재하지 않습니다


사용하는 목적은

1. 대용량 쿼리 혹은 복잡도가 높은 쿼리를 단순하게 하기위해

2. 보안을 위해


뷰의 단점

수정이 복잡하다

에러가 발생하여 수정하여도 바로 돌아가지 않습니다 컴파일을 해주어야 합니다


뷰의 종류 

테이블의 개수에 따라서

단순뷰 = 1개

복합뷰 = 2개 이상



뷰의 생성






시퀀스(Sequence)

자동증가를 뜻합니다 

혼자서는 아무런 동작을 하지 않습니다

99% insert 문과 같이합니다



순환 : 컬럼의 크기가 제한되 크기 까지 왔을때 그이상 증가 시켜줍니다


소스

 INSERT INTO DEPT1

  (DEPTNO, DNAME, LOC

  ) VALUES

  (emp1_seq.nextval,'총무부','부산');







Posted by mantwo

decode

: 다중 조건으로 결과값을 얻을수 있습니다



 docode문

 case문

select

  ename,

  deptno,

  decode(deptno,10,'ACCOUNTING'

               ,20,'RESERCH'

               ,30,'SALES'

               ,40,'OPERATIONS') dname

 from emp; 

select

  ename,

  deptno,

  case deptno select

      when 10 then 'ACCOUNTING'

      when 20 then 'RESERCH'

      when 30 then 'SALES'

      when 40 then 'OPERATIONS'

      end dname

 from emp;


단점 : 느립니다


문제> 매니저는 임금을 15%인상하고 사원들은 임금을 5%로 인사하도록 작성하되 decode를 사용하세요


그룹함수


최소 최대 합계 평균 집계 분산 편차



 문제>사원들이 몇년도에 입사하였는지 조사하여 입사 년도별로 그해 입사한 인원수를 구하는 쿼리



 select

   deptno,

   count(*) as "총인원",

   sum(decode(to_char(hiredate,'YYYY'),1980,1,0)) as "1980",

   sum(decode(to_char(hiredate,'YYYY'),1981,1,0))as "1981",

   sum(decode(to_char(hiredate,'YYYY'),1982,1,0))as "1982",

   sum(decode(to_char(hiredate,'YYYY'),1987,1,0))as "1987"

 from emp

 group by deptno;




문제>이름에 A가들어가는 사원들의 이름과 부서이름을 출력하나


select ename, dname

from emp e,dept d

where e.deptno = d.deptno

and ename like '%A%';


commit / rollback


TABLE을 생성 => DDL  중요!!!auto commit

DATA를 생성 => DML 

DATA를 관리 => DCL


*데이터를 넣거나 수정등의 작업이 발생하면 commit,rollback를 해야합니다!


설계    =>    저장    =>    화면

      부분반영


inser / update / delete


사용시 주의 사항  not null => FK





Posted by mantwo

Overloading(오버로딩)

:객체 지향 컴퓨터 프로그래밍에서 다형성의 특정 경우로 다른 연산자들이 함수 인자를 통해서 구현을 할 때를 말다. 연산자 오버로딩은 일반적으로 언어, 프로그래머, 또는 두 가지 모두에 의해 정의된다.


쉽게 설명하자면 같은 생성자 매소드등에서 매개변수가 다른 생성자 매소드들을 생성하여 필요에 맞게 선택하여 사용하는 것을 뜻합니다


더 쉽게 설명하자면

 public man(){  

    1번

 }

 public man(int i){

     2번

 }

 public man(string){

    3번 

}


 객체 생성

 man m = new man();    => 1번

 man m = new man(2);   => 2번

 man m = new man("안녕하세요");    => 3번


그렇다면 이러한 오버로딩을 일상생활의 예를 통하면 구현을 해보도록 합시다


사과장수 

의 예를 통하여 이해를 해보도록 하겠습니다


"사과 장수가 사과를 팔고 있습니다"

"첫번째 사람에게 몇개를 팔고 얼마를 벌었습니다"

"두번째 사람에게 몇개를 팔고 얼마를 벌었습니다"

"세번째 사람에게 몇개를 팔고 얼마를 벌었습니다"


반대로

"첫번째 사람은 사과를 몇개 구매하고 얼마를 지출하였습니다.....생략"


설계

사과 장수가 있고 구매자가 3명있습니다

구매자는 각각 다른 수량, 단가로 사과장수로 부터 사과를 구매합니다

사과를 판매한 사과 장수에는 판매한 개수와 벌어들인 수입이 출력됩니다

사과를 구매한 구매자는 구매한 사과 개수와 지출한 금액을 출력합니다



만들려고 하는 프로그램을 간단하게 표로 나타내다면

FruitBuyer 구매자

생성자()


구매()


결과 출력()


FruitSeller 판매자

 

생성자()


판매()

결과출력()

FruitMain 

객체생성
판매자 
구매자1, 구매자2, 구매자3
 

4개의 매소드와 2개의 생성자 4개의 객체를 생성합니다


실행단계

FruitMain 객체생성 => FruitBuyer3 매소드 호출 및 FruitSeller3 값(사과개수)전달 다시 값(사과개수) 전달 및 결과 출력 => FruitBuyer3 값을 받아 결과 출력  => 종료!! 



소스보기

 package day06;

 

class FruitSeller3{

           int numOfApple;

           int myMoney;

           int Apple_Price;

 

           public FruitSeller3(int myMoney,    int numOfApple, int Apple_Price) {

                     this.myMoney = myMoney;

                     this.numOfApple = numOfApple;

                     this.Apple_Price = Apple_Price;               

           }

           public int saleApple(int price){

                     int num = price/Apple_Price;

                     numOfApple -= num;

                     myMoney += price;

                     return num;

           }

           public void showSaleResult(){

                     System.out.println("남은 사과  : " + numOfApple );

                     System.out.println("판매 수익  : " + myMoney);

           }

}

class FruitBuyer3{

           int numOfApple = 0;

           int myMoney = 10000;

                    

           public void buyApple(FruitSeller3 s, int price){

                     int num = s.saleApple(price);

                     numOfApple += num;

                     myMoney -= price;                   

           }

           public void showSaleResult(){

                     System.out.println("사과 개수  : " + numOfApple);

                     System.out.println("현제 잔액  : " + myMoney);

           }

}

public class FruitSalesMain3 {

                    

           public static void main(String[] args) {

 

                     FruitBuyer3 b = new FruitBuyer3();

                     FruitSeller3 s1 = new FruitSeller3(0,30,1500);

                     FruitSeller3 s2 = new FruitSeller3(0,20,1000);

                     FruitSeller3 s3 = new FruitSeller3(0,10,2000);

                     /*

                     //금액, 수량, 단가                               

                     s1.initMember(0,30,1500);

                     s2.initMember(0,20,1000);

                     s3.initMember(0,10,2000);           

                     */

                     b.buyApple(s1,4500);

                     b.buyApple(s2,1000);

                     b.buyApple(s3,2000);

                    

                     System.out.println(s1);

                    

                     System.out.println("---판매자1의 현재 상황");

                     s1.showSaleResult();                 

                     System.out.println("---판매자2의 현재 상황");

                     s2.showSaleResult();                 

                     System.out.println("---판매자3의 현재 상황");

                     s3.showSaleResult();                 

                                         

                     System.out.println("---구매자의 현재 상황");

                     b.showSaleResult();

           }

}




Posted by mantwo

.dual

:가상테이블을 뜻합니다


두 쿼리문의 차이는 무엇일까요?

select 30*60

from dual;


select 30*60

from emp;


결과확인

   



.emp table



number(4,0) => 4는 4byte를 뜻합니다 오라클에서는 오직 number형으로만 사칙연산이 가능합니다

                      to_number() : 정수로 만들어주는 함수입니다

varchar2(7,2) => 2000byte를 담을수 잇습니다, (7,2) 7은 7자리를 뜻하면 2는 소수점 자리를 뜻합니다 7자리중 정수자                      

                     리는 나머지 5자리입니다

null => 아직 확정되지 않은 값을 뜻합니다


참고> 사칙연산 : 1년 연봉을 계산한다고 가정했을때 연산을 한다면 

sal*12*comm을 사용한다면 

다른 값은 문제가 되지 않지만 null을 사용한 값은 연산이 되지 않습니다


수정한다면 NVL을 사용하여

select 

    ename,

    sal,

    sal*12,

    sal*12+NVL(comm,0) as "연봉"

from emp;


as(alias) :  표준 sql구약에 의하면 alias를 사용한다면 as를 항상 사용합니다 사용상의 차이는 없습니다



.distinct

:


select
     distinct deptno
from emp; 

select
     deptno

from emp

group by deptno;



날짜형을 바꾸고 싶다면?

기존 날짜는 82/12/02로 출력됩니다


방법은 환경설정에 NLS를 수정하며 바꾸는 방법과

형변환을 시켜주는 방법이 있습니다


select

   ename,

   to_char(hiredate,'YYYY-MM-DD')

from emp;


하지만 쿼리문의 경우에는 테이블의 데이타가 100만건이면 100만건 형변환을 시켜주기 때문에 가장 좋은방법은

환경설정을 바꿔주거나 처음 만들때부터 원하는 날짜로 입력합니다


추가로 기본적으로  82/12/02로 보이지만

select

    ename,hiredate

from emp

where hiredate >= '1982-01-01';




Wild Card(와일드카드)

: 문자를 대체 한다는 의미로 %, _ 사용하며 주로 like를 사용하여 문자를 검색하여 출력할때 사용합니다


A로 시작하는 이름을 검색하세요!


select

   ename,

   hiredate

from emp

where ename like 'A%';


3번째 문자가 R로 시작하는 이름을 검색하세요

where ename like '__R%';





 in연산자

:


코드를 먼저 보자면

보너스가 300 500 1400 인사람을 검색한다면

select 

   ename,

   hiredate,

   comm

from emp

where comm=300 or comm=500 or comm=1400;


이것을 in연산자로 사용하면

where comm in (300,500,1400);


*단 같은 컬럼내에서만 가능합니다



is null / is not null


코드를 보자면

이것은 맞을까 틀릴까?

where mgr = null;


정답은 틀렸습니다 

null은 확정되지않은 값으로 비교연산을 수행 할 수 없습니다


null인지 아니지를 판단하기 위해서 사용하는 것이

is null / is not null   입니다



round / trunc

: 반올림과 버림입니다 사용방법은 간단합니다


 반올림

버림 

select round(45.193,2)

from dual;

select trunc(45.196,2)

from dual; 

 45.19 45.19



문제>사원번호가 홀수인 사원들의 이름을 출력하시오

보통 이렇게 많이 생각합니다

where (to_number(empno)%2) = 1;


하지만 실행되지 않습니다 수정한다면 아래와 같습니다


select 

empno,

ename

from emp

where mod(empno,2) =1 ;





Posted by mantwo

VIEW의 분

:각각의 쿼리에 서브쿼리가 등장했을때 부르는 명칭이랑 쓰임새가 약간씩 다름니다.

 

참고 서브쿼리 : 쿼리안의 도 다른 쿼리를 뜻합니다 주로 where절에 오는 경우를 뜻합니다

 

select => 스칼라뷰(서브쿼리,하의질의) : 하나의 데이터를 리턴시켜주는 질의 

from => 인라인뷰(서브쿼리,하의질의) : 하나의 가상 테이블을 리턴시켜주는 질의

where => (서브쿼이(하의질의)) : 조건값들을 리턴시켜주는 질의

 

 

 인라인뷰
 SELECT emp.부서이름,emp.부서코드,emp.사원이름,emp.최대임금
 FROM (SELECT A.부서명 AS 부서이름,B.부서코드,B.사원이름,C.월급 AS 최대임금
                            ,RANK()  OVER(PARTITION BY 부서코드 ORDER BY 월급 DESC) AS 월급순위
             FROM JOB_EMP A,JOB_MEMBER B,JOB_SAL C
             WHERE A.부서코드=B.부서코드 AND B.직급코드=C.직급코드
             ORDER BY B.부서코드
             ) emp
WHERE emp.월급순위=1

 

 

 서브쿼리

 SELECT emp.EMPLOYEE_ID 사원번호, emp.LAST_NAME 이름, emp.SALARY 급여, dept.DEPARTMENT_NAME
  FROM EMPLOYEES emp, DEPARTMENTS dept
  WHERE emp.DEPARTMENT_ID = dept.DEPARTMENT_ID
  AND (dept.DEPARTMENT_ID,emp.SALARY) IN (
                      SELECT DEPARTMENT_ID, MAX(salary)
                      FROM EMPLOYEES
                      GROUP BY DEPARTMENT_ID
                    )
  ORDER BY emp.EMPLOYEE_ID asc;

 

 

 

 

오라클의 분석함수

 

  RANK() 함수
    순위를 리턴하는 함수입니다
    공동 순위가 있을경우 중복으로 표시됩니다 예를들어 2위가 2명이다면 둘다 2위로 표시됩니다
   

  OVER() 함수
    order by, group by 서브쿼리의 정렬 및 그룹선언 함수입니다 

 

기본형식

 select employee_id,
      salary,
      rank() over(order by salary desc)s_ranking
from employees;

 

 

ROW_NUMBER()

  ROW_NUMBER()함수는 1부터 시작해서 각 row(데이터값)별로 순차적으로 리턴한다.
  RANK(), DENSE_RANK()가 동일한 값이 있을경우 동일한 순번을 리턴하지만,
  ROW_NUMBER()는 무조건 순서대로 순번을 리턴한다.

 

예제) 부서별 급여순위 3위 까지 조회 인라인뷰를 이용하여 

select t.*
from(
    select department_id,
            last_name,
            salary,
            row_number() over(partition by department_id order by salary desc)sal
            from employees
        )t
where t.sal <=3;

 

 

Posted by mantwo

하위질의

: 하나의 sql문에 두개 이상의 select문이 포함되는 경우를 말합니다.

 

예제1_서브쿼리)2000년 이후 입사한 사원 중 대표이사를 제외한 전체 사원들의 평균 급여 보다 많이 받은 사원들을 얻어봅니다.

 

먼저2000년 이후 입사한 사원들을 구합니다 

 select employee_id

         ,first_name

         ,job_id

         ,salary

 from employees

 where extract(year form hire_date) >=2000;

 

그리고 대표이사를 제외한 전체 사원을 대상으로 평균급여를 구합니다

 select avg(salary)

 from employees

 where manager_id is not null;

 

대표이사는 null

평균 연봉은 6296.2264가 나옵니다 이것을 

 select employee_id

         ,first_name

         ,job_id

         ,salary

 from employees

 where extract(year form hire_date) >=2000

 and salary > 6296.2264

 and manager_id is not null;

 

라고 할수있지만 값을 구한다음에 다시 쿼리를 작성하면 좋은 쿼리라 할수없습니다 값을 구하고 결과까지 보여주기위해서는 서브쿼리를 이용하는 방법이 있습니다

 

결론적으로 서브쿼리를 이용한다면

 select employee_id

         ,first_name

         ,job_id

         ,salary

 from employees

 where extract(year form hire_date) >=2000

 and salary > (select avg(salary)

                     from employees

                     where manager_id is not null

);

 

서브쿼리의 구조를 보면

3번째 결과에 2번의 평균 연봉을 구하는 쿼리가 서브로 들어가 있는 겄을 확인 할 수있습니다. 쿼리를 작성하는데있어서 한번에 깔끔한 쿼리즐 작성하면 좋지만 그렇지 못하다면 하나하나 나누어보고 대입해 보는것도 좋은 방법입니다.

 

 

예제2_join) 조건은 아래와 같습니다

 

    질)부서별로 최대급여를 받는 사원의 정보를 출력하라.
    EMPLOYEES emp(예명)
    DEPARTMENTS dept(예명)
   
    사원번호/이름/급여/부서이름
    emp.employee_id/emp.last_name/emp.salary/dept.department_name
   

    결과)
    사원번호  / 이름      / 급여  / 부서이름
      100       King           24000   Executive
      103       Hunold        9000   IT
      108       Greenberg  12008   Finance
      114       Raphaely    11000   Purchasing
      121       Fripp           8200   Shipping
      145       Russell      14000   Sales
      200       Whalen        4400   Administration
      201       Hartstein    13000   Marketing
      203       Mavris        6500   Human Resources
      204       Baer         10000   Public Relations
      205       Higgins     12008   Accounting

 

 

1)먼저 고민해야 될부분이 예명을 사용하고 두테이블의 비교니 join 을 합니다 

 select employee_id as 사원번호,last_name as 이름,salary as 급여,department_name as 부서이름
 from employees emp,departments depa
 where emp.department_id = depa.department_id

 

 

2)그리고 부서별로 최고액 연봉자를 구합니다

 select department_id, max(salary)
 from employees
 group by department_id           

 

 

1)번과 2번을 합친다면

 select employee_id as 사원번호,last_name as 이름,salary as 급여,department_name as 부서이름
 from employees emp,departments depa
 where emp.department_id = depa.department_id
 and 컬럼  연산 
              select department_id, max(salary)
              from employees
              group by department_id           
 );

 

 

컬럼 연산에 서브에서 받은 값이 department_id,salary이고 이것에 해당하는 값이니 IN을 사용합니다 

 select employee_id as 사원번호,last_name as 이름,salary as 급여,department_name as 부서이름
 from employees emp,departments depa
 where emp.department_id = depa.department_id
 and (depa.department_id,emp.salary)in(
              select department_id, max(salary)
              from employees
              group by department_id           
 );

 

 

Posted by mantwo