학원 37일차 - Oracle

·2021년 7월 10일
0

2021.05.20

ex20_join.sql

관계형 데이터

직원 정보 테이블

  • 직원번호, 직원명, 급여, 거주지, 담당프로젝트

상황 1. 테이블을 하나로 조작

-- 테이블 생성
create table tblStaff(
    
    seq number primary key,         -- 직원번호(PK)
    name varchar2(30) not null,     -- 직원명
    salary number not null,         -- 급여
    address varchar2(300) not null, -- 거주지
    project varchar2(300) null      -- 담당프로젝트

);

insert into tblStaff(seq, name, salary, address, project) values (1,'홍길동', 300, '서울시', '홍콩수출');
insert into tblStaff(seq, name, salary, address, project) values (2,'아무개', 250, '부산시', 'tv광고');
insert into tblStaff(seq, name, salary, address, project) values (3,'하하하', 280, '대전시', '매출분석');
  • 1명의 직원이 2개 이상의 프로젝트를 담당했을때

    • Case A. 홍길동
      • 프로젝트 1개당 레코드 1개
      • 직원정보가 계속 반복(★★★★)
    • Case B. 호호호
      • 프로젝트 전부를 1개의 컬럼에 누적
      • 직원 정보가 유일(1개 레코드)
  • => 결론 : 둘 다 좋은 방식이 아님 -> 테이블 설계의 miss...

-- 2번째 프로젝트
-- 홍길동 + 프로젝트 1건 추가(고객관리)
insert into tblStaff(seq, name, salary, address, project) values (4,'홍길동', 300, '서울시', '고객관리');

-- 호호호 + 2개 프로젝트
insert into tblStaff(seq, name, salary, address, project) values (5,'호호호', 270, '의정부시', '홍콩수출,고객관리');

-- 홍길동 급여 수정
update tblStaff set salary = 310 where seq = 1; -- 홍길동은 1번 4번에 있음... -> 1번 홍길동만 급여가 310으로 바뀜 -> 무결성이 깨짐

-- 3번째 프로젝트
-- 홍길동 + 프로젝트 추가
insert into tblStaff(seq, name, salary, address, project) values (6,'홍길동', 300, '서울시', '반품처리');

-- 호호호 + 프로젝트 추가
update tblStaff set project = project || ', 반품처리' where seq = 5;

-- 홍길동 고객관리 -> 담당 해체
delete from tblstaff where seq = 4;

-- 호호호 고객관리 -> 담당 해제
update tblStaff set project = replace(project, '고객관리,', '') where seq = 5; -- 특정 프로젝트만 지정해서 수정하기 어렵다.

select * from tblstaff;

상황 2. 테이블을 두개로 분리

drop table tblstaff;
drop table tblProject;

-- (부모테이블)
create table tblStaff(
    
    seq number primary key,         -- 직원번호(PK)
    name varchar2(30) not null,     -- 직원명
    salary number not null,         -- 급여
    address varchar2(300) not null  -- 거주지

);

create table tblProject(
    
    seq number primary key,         -- 프로젝트 번호(PK)
    project varchar2(300) null,     -- 담당프로젝트
    staff_seq number not null       -- 직원번호    
    
);

insert into tblStaff(seq, name, salary, address) values (1,'홍길동', 300, '서울시');
insert into tblStaff(seq, name, salary, address) values (2,'아무개', 250, '부산시');
insert into tblStaff(seq, name, salary, address) values (3,'하하하', 280, '대전시');

insert into tblStaff(seq, name, salary, address) values (5,'후후후', 250, '서울시');

insert into tblProject(seq, project, staff_seq) values (1, '홍콩수출', 1);
insert into tblProject(seq, project, staff_seq) values (2, 'Tv광고', 2);
insert into tblProject(seq, project, staff_seq) values (3, '매출분석', 3);


-- 홍길동 + 프로젝트 1개 추가
insert into tblProject(seq, project, staff_seq) values (4, '노조협상', 1);

-- 홍길동 + 프로젝트 1개 해제
delete from tblProject where seq = 1;

select * from tblstaff;
select * from tblProject;
-- 위의 2개의 테이블의 문제점!!
-- A. 신입 사원 입사 -> 신규 프로젝트 담당 
-- A.1 신입 사원 추가(o)
insert into tblStaff(seq, name, salary, address) values (4,'호호호', 200, '서울시');

-- A.2 신규 프로젝트 추가(o)
insert into tblProject(seq, project, staff_seq) values (5, '자재매입', 4);

-- A.3 신규 프로젝트 추가(x)
insert into tblProject(seq, project, staff_seq) values (6, '고객유치', 5); -- 없는 직원(데이터)번호 사용 -> 있는 직원번호인지 아닌지 체크 해야함!!!


-- B. '홍길동'퇴사
-- B.1 '홍길동'삭제(x)
delete from tblStaff where seq = 1; -- 존재하지 않는 직원이 프로젝트를 담당하게됨..

-- B.2 '홍길동'의 모든 업무 > 위임(업무 인수인계)
update tblProject set staff_seq = 2 where staff_seq = 1;

-- B.3 '홍길동' 삭제(o)
delete from tblStaff where seq = 1;

상황3. 외래키(FK) 사용

-- (부모테이블)
create table tblStaff(
    
    seq number primary key,         -- 직원번호(PK)
    name varchar2(30) not null,     -- 직원명
    salary number not null,         -- 급여
    address varchar2(300) not null  -- 거주지

);

-- 수정★★★★
-- (자식테이블)
create table tblProject(
    
    seq number primary key,                                  -- 프로젝트 번호(PK)
    project varchar2(300) null,                              -- 담당프로젝트
    -- staff_seq에 들어가는 번호는 tblSatff(seq)를 참조한다.
    staff_seq number not null references tblStaff(seq)       -- 직원번호(FK, Foreign Key, 외래키, 참조키)   
);

-- tblStaff    - tblProject
-- PK(부모키)  - FK(자식키)
-- 부모        - 자식
-- 부모테이블   - 자식 테이블

insert into tblStaff(seq, name, salary, address) values (1,'홍길동', 300, '서울시');
insert into tblStaff(seq, name, salary, address) values (2,'아무개', 250, '부산시');
insert into tblStaff(seq, name, salary, address) values (3,'하하하', 280, '대전시');

insert into tblProject(seq, project, staff_seq) values (1, '홍콩수출', 1);
insert into tblProject(seq, project, staff_seq) values (2, 'Tv광고', 2);
insert into tblProject(seq, project, staff_seq) values (3, '매출분석', 3);


-- A. 신입 사원 입사 -> 신규 프로젝트 담당 
-- A.1 신입 사원 추가(o)
insert into tblStaff(seq, name, salary, address) values (4,'호호호', 200, '서울시');

-- A.2 신규 프로젝트 추가(o)
insert into tblProject(seq, project, staff_seq) values (5, '자재매입', 4);

-- A.3 신규 프로젝트 추가(x)
-- ORA-02291: integrity constraint (HR.SYS_C007173) violated - parent key not found
-- 에러 : 무결성 제약조건이 위배되었습니다.(부모키가 없습니다.)
-- insert into tblProject(seq, project, staff_seq) values (6, '고객유치', 5); -- 존재하지 않는 직원번호를 사전에 막음


-- B. '홍길동'퇴사
-- B.1 '홍길동'삭제(x)
-- ORA-02292: integrity constraint (HR.SYS_C007173) violated - child record found
-- 무결성 제약조건이 위배되었습니다.(자식 레코드가 발견되었습니다.)
-- 홍길동을 참조하고 있는 데이터가 있기 때문에 홍길동을 삭제하면 참조데이터가 이상해질 수 있기 때문에 에러가 난다.
delete from tblStaff where seq = 1;

-- B.2 '홍길동'의 모든 업무 > 위임(업무 인수인계)
-- 홍길동이 업무를 위임하면 참조하는 데이터가 없기 때문에 위임을 해야 삭제 가능.
update tblProject set staff_seq = 2 where staff_seq = 1;

-- B.3 '홍길동' 삭제(o)
delete from tblStaff where seq = 1;

관계를 맺고 있는 2개의 테이블을 조작하면 발생하는 일

  • 이 규칙이 깨지면 데이터 무결성(유효성)이 깨진다. > 데이터 가치 상실
  • 반드시 지켜야하는 상황
  1. 부모 테이블 조작. tblStaff
    a. 행추가(insert) : 아무 영향 없음 ex) 신입사원 추가
    b. 행수정(update) : 아무 영향 없음 ex) 직원 한명이 급여 인상
    c. 행삭제(delete) : 자식 테이블에 자신을 참조하는 행이 존재하는지 반드시 사전 체크 요망!!! > FK 존재 유무 체크!!!> child record found -> 자신을 참조하고 있는 행이 있으면 삭제 불가 ex) 직원 퇴사
  1. 자식 테이블 조작. tblProject
    a. 행추가(insert) : 자신이 참조하는 대상이 실제로 부모테이블에 존재하는 값인지 사전 체크 요망!! > parent key not found ex) 신규 프로젝트 추가
    b. 행수정(update) : 수정할 컬럼이 FK 컬럼 > 부모 테이블에 존재하는 값인지 사전 체크 요망 !! > parent key not found
    c. 행삭제(delete) : 아무 영향 없음 ex) 프로젝트 폐지 -> 직원에 영향을 주지 않음

exerd - 테이블과 테이블의 관계를 다이어그램으로 그리는 프로그램

image-20210520111943212


관계를 맺고 있는 테이블 생성하기

  • 2개의 테이블 중 누가 부모 테이블이 되고, 누가 자식 테이블이 되야하는지??
  • 2개의 테이블의 데이터 중 시간 흐름 순서상 누가 먼저 생겨나야하는지? 먼저 생성할 데이터(부모테이블), 나중에 생성할 데이터(자식 테이블) ★★★
-- tblcustomer이 자식 테이블이라고 가정했을때
-- 고객 <-> 판매
-- 1. 고객이 회원가입 > 신규회원은 판매내역이 없음 > sseq 비워둔채 가입
-- 2. 구매 > insert(tblSales) + update(tblCustomer) 판매내역 갱신
-- 3. 또 다른 물건 구매 > insert(tblSales) + update(tblCustomer) -> 이미 1이 들어있음 -> "1,2"  -> 데이터 관리 어려움..

-- tblsales가 자식 테이블이라고 가정했을때
-- 1. 고객이 회원가입 -> 비워두는 컬럼없음
-- 2. 구매 > insert(tblSales)
-- 3. 또 다른 물건 구매 > insert(tblSales)

-- 고객 테이블 (부모 테이블)
create table tblcustomer(
    seq number primary key,                      -- 고객번호(PK)
    name varchar2(30) not null,                  -- 고객명
    tel varchar2(15) not null,                   -- 연락처
    address varchar2(100) not null               -- 주소
    -- sseq number null reference tblSales(seq)  -- 참조키(판매내역번호) -> 신규회원은 이용내역이 없음 -> null
);


-- 판매 내역 테이블 (자식 테이블)
create table tblsales(
    seq number primary key,                                 -- 판매번호(PK)
    item varchar2(50) not null,                             -- 제품명
    qty number not null,                                    -- 수량
    regdate date default sysdate not null,                  -- 판매날짜
    -- 두테이블을 관계를 맺을때는 자식 테이블이 부모 테이블의 primary key를 참조한다.(유일하게 구별할 수 있는 식별자)★★★ 
    cseq number not null references tblCustomer(seq)        -- 고객번호(FK) -> 누가 사갔는지 알아야하기 때문에 not null
);

select * from tblcustomer;
select * from tblsales;

관계를 맺고 있는 테이블들의 생성과 삭제 ★★★

  1. 생성 : 부모 테이블 생성 -> 자식 테이블 생성
  2. 삭제 : 자식 테이블 삭제 -> 부모 테이블 삭제
--  비디오 대여점

drop table tblGenre;
drop table tblVideo;
drop table tblMember;
drop table tblRent;

-- 장르 테이블
create table tblGenre (
    seq number primary key,                         -- 장르번호(PK)
    name varchar2(30) not null,                     -- 장르명
    price number not null,                          -- 대여가격 (장르별로 가격이 다름)
    period number not null                          -- 대여기간(일) (장르별로 대여기간이 다름)
);

-- 비디오 테이블
create table tblVideo (
    seq number primary key,                         -- 비디오번호(PK)
    name varchar2(100) not null,                    -- 제목
    qty number not null,                            -- 보유 수량
    company varchar2(50) null,                      -- 제작사
    director varchar2(50) null,                     -- 감독
    major varchar2(50) null,                        -- 주연배우
    genre number not null references tblGenre(seq)  -- 장르(FK)
);

-- 고객 테이블
create table tblMember (
    seq number primary key,                         -- 회원번호(PK)
    name varchar2(30) not null,                     -- 회원명
    grade number(1) not null,                       -- 회원등급(1,2,3)
    byear number(4) not null,                       -- 생년
    tel varchar2(15) not null,                      -- 연락처
    address varchar2(300) not null,                 -- 주소
    money number not null                           -- 예치금
);

-- 대여 테이블
create table tblRent (
    seq number primary key,                                 -- 대여번호(PK)
    member number not null references tblMember(seq),       -- 회원번호(FK)
    video number not null references tblVideo(seq),         -- 비디오번호(FK)
    rentdate date default sysdate not null,                 -- 대여시각
    retdate date null,                                      -- 반납시각 -> 언제 반납하는지 알 수 없기때문에 null
    remark varchar2(500) null                               -- 비고
);


-- 시퀀스 생성
create sequence genreSeq;
create sequence videoSeq;
create sequence memberSeq;
create sequence rentSeq;

-- 시퀀스 삭제 
drop sequence genreSeq;
drop sequence videoSeq;
drop sequence memberSeq;
drop sequence rentSeq;

-- 테이블 확인
select * from tblGenre; 	-- 6개
select * from tblVideo;		-- 11개
select * from tblMember; 	-- 10개
select * from tblRent; 		-- 6개

-- 테이블 내용 삭제
delete from tblGenre;
delete from tblVideo;
delete from tblMember;
delete from tblRent;

image-20210520204107962


조인, Join

  • (서로 관계를 맺고 있는) 2개(1개) 이상의 테이블의 내용을 동시에 가져와서 1개의 결과셋을 만드는 작업
  • 조인에서 컬럼은 반드시 테이블명(소유주)을 적는게 좋다. (충돌 발생)

조인의 종류(ANSI-SQL기준)

  1. 단순 조인, cross join
    • 사용 거의 안함 > 결과셋에 유효한 레코드와 유효하지 않은 레코드가 뒤섞여 있기 때문에
    • 가끔씩 개발자가 테스트 용도의 큰 데이터가 필요한 경우에 사용(더미 데이터 - 유효성과 무관한)
    • select * from tbleA cross join tbleB;
    • select * from tbleA, tbleB;
  2. 내부 조인, inner join (★★★★★)
    • 단순 조인의 결과셋에서 유효한 레코드만 추출한 조인
    • 두 집합의 교집합같은 성질
    • select * from tableA inner join tableB on tableA.PK = tableB.FK;
  3. 외부 조인, outer join (★★★★★)
    • 내부 조인 + 부모 테이블
    • 내부 조인 + 차집합(부모테이블)
    • 내부 조인의 결과셋에 참조되지 않은 부모 레코드를 더한 결과셋
    • 일반적으로는 부모테이블을 가르킨다.(left or right)
    • select * from tableA left outer join tableB on tableA.PK = tableB.FK;
  4. 셀프 조인, self join
    • 1개의 테이블을 사용해서 조인
    • 셀프 조인 + 단순 조인
    • 셀프 조인 + 내부 조인
    • 셀프 조인 + 외부 조인
  5. 전체 외부 조인, full outer join
    • left outer join + right outer join
단순 조인, cross join
select * from tblcustomer; -- 3건
select * from tblSales; -- 9건

-- tblCustomer + tblSales
select * from tblCustomer cross join tblSales; -- 27건, --> ANSI SQL
select * from tblCustomer, tblSales; --> Oracle

-- 개발자가 테스트 용도의 큰 데이터가 필요한 경우에 사용 - 더미 데이터
select * from tbladdressbook cross join tblComedian cross join tblCountry; -- 여러개 조인


내부 조인, inner join
select * from tblcustomer;
select * from tblSales;

-- 고객정보와 판매내역을 동시에 가져오기
select * from tblCustomer
    inner join tblSales
    -- tblCustomer.seq과 tblSales.cseq에서 똑같은 값만 가져와라
        on tblCustomer.seq = tblSales.cseq; -- 어떤 레코드만 남길지에 대한 조건(부모테이블.PK = 자식테이블.FK)
        
        
-- cross조인에서 유효한 것만 추출해서 inner조인처럼 만든 것
select * from tblCustomer 
    cross join tblSales
        where tblCustomer.seq = tblSales.cseq; --  사용안함

-- ORA-00918: column ambiguously defined (열의 정의가 애매합니다.)
-- 조인을 할 때 자주 발생하는 현상
-- select seq from tblCustomer -> seq가 양쪽 테이블의 어느 것인지 알 수 없음
select 
    tblCustomer.seq, tblSales.seq
from tblCustomer -- 조인에서 컬럼은 반드시 테이블명(소유주)을 적는게 좋다. (충돌 발생) ★★
    inner join tblSales
        on tblCustomer.seq = tblSales.cseq;
        
        
-- 보고 싶은 내역만 구분해서 가져오기
select 
    tblCustomer.name, -- 테이블명을 붙이면 가독성이 좋아진다.
    tblCustomer.address,
    tblSales.item,
    tblSales.qty
from tblCustomer    
    inner join tblSales
        on tblCustomer.seq = tblSales.cseq;
-- 테이블 별칭은 as를 쓰지 않는다. (보통은 1글자로 만든다.)
select 
    c.name,
    c.address,
    s.item,
    s.qty
from tblCustomer c   
    inner join tblSales s
        on c.seq = s.cseq;    

select * from tblStaff;
select * from tblProject;

select 
    s.name as 직원명,
    s.salary as 급여,
    p.project as 프로젝트명
from tblStaff s
    inner join tblProject p
        on s.seq = p.staff_seq;

-- FK안한 관계있는 테이블끼리 Join
select * from tblMen;
select * from tblWomen;


select 
    m.name as 남자,
    f.name as 여자
from tblMen m 
    inner join tblWomen f 
        on m.couple = f.name;    

-- 전혀 관계없는 케이블끼리 join -> 의미없음.. -> join이 된다고 해도 무조건 하면 XXX
select * from tbladdressbook;
select * from tblComedian;


select * from tbladdressbook a
    inner join tblcomedian c
        on a.height = c.height;
-- 직원의 이름과 부서명을 가져오시오.
select * from locations;
select * from employees;
select * from departments;

-- 상관서브쿼리
select
    first_name || last_name as name,
    -- department_id,
    (select department_name from departments where department_id = employees.department_id) as department
from employees;


-- inner join (3개 테이블)
select
    e.first_name || ' '  || e.last_name as name,
    d.department_name,
    l.city || '' || l.street_address
from employees e
    inner join departments d
        on d.department_id = e.department_id
            inner join locations l
                on l.location_id = d.location_id;
select * from tblgenre;
select * from tblvideo;


-- tblgenre + tblvideo
select
    *
from tblgenre g
    inner join tblvideo v
        on g.seq = v.genre;
        
        
-- tblgenre + tblvideo + tblRent
select
    *
from tblgenre g
    inner join tblvideo v
        on g.seq = v.genre
            inner join tblRent r
                on v.seq = r.video;
        
        
        
        
-- tblgenre + tblvideo + tblRent + tblMember
select * from tblgenre;

select
    g.price as 대여가격,
    g.period as 대여기간,
    v.name as 비디오제목,
    m.name as 회원명,
    r.rentdate as 대여날짜,
    r.rentdate + g.period as 반납마감날짜
from tblgenre g
    inner join tblvideo v
        on g.seq = v.genre
            inner join tblRent r
                on v.seq = r.video
                    inner join tblMember m
                        on m.seq = r.member;
select * from tblStaff; -- 부모 테이블
select * from tblProject; -- 자식 테이블
   
-- 내부 조인
-- : 2개 테이블에 on 조건을 만족하는 레코드만 반환
-- : 내부 조인의 결과는 대부분 자식 레코드 수만큼 나온다.
select
    *
from tblStaff s
    inner join tblProject p
        on s.seq = p.staff_seq;
-- 비디오 가게 사장
-- : 출근 > 어떤 회원?이 뭘 대여? 반납O,X?
select
    m.name as 이름,
    v.name as 타이틀,
    r.retdate as 반납여부
from tblMember m
    inner join tblRent r
        on m.seq = r.member
            inner join tblvideo v
                on v.seq = r.video;
                -- inner join은 양쪽 테이블에 존재하는 데이터만 가져온다.(교집합)
                

select * from tblCustomer; -- 3명 -> 4명
select * from tblSales; -- 9명

-- 신규 가입 회원은 아직 구매 이력이 없다.(****)
insert into tblCustomer values (4,'호호호','010-8745-9652', '서울시');

-- 구매 이력과 구매 이력이 있는 회원정보를 가져오세요. 
select * from tblcustomer c
inner join tblSales s
    on c.seq = s.cseq;

sub Query vs Join

select * from tblCustomer; -- 부모 -> 고객명, 연락처
select * from tblSales; -- 자식 -> 제품명, 수량    

-- join
select 
    c.name,
    c.tel,
    s.item,
    s.qty
from tblCustomer c   
    inner join tblSales s
        on c.seq = s.cseq;
        

-- sub Query(상관 서브 쿼리) -> 자식 테이블이 메인이 되어야한다. 
select item, qty, cseq, 
    (select name from tblCustomer where tblCustomer.seq = tblSales.cseq)as name, 
    (select tel from tblCustomer where tblCustomer.seq = tblSales.cseq) as tel
from tblSales;  

외부 조인, outer join
-- 구매 이력과 상관없이 모든 회원 정보를 가져오되, 구매 이력이 있으면 구매이력도 같이 가져오시오.
-- tblcustomer(부모테이블) 를 가르킨다.
select * from tblcustomer c left outer join tblSales s on c.seq = s.cseq; -- 물건을 한번도 안 산 신규회원 포함

select * from tblcustomer c right outer join tblSales s on c.seq = s.cseq;
--  대여 유무 이력과 상관없이 모든 회원 정보 + 대여기록
select
    m.name as 이름,
    r.rentdate,
    r.retdate as 반납여부
from tblMember m
    left outer join tblRent r
        on m.seq = r.member;


select
    distinct
    m.name as 이름,
    case
        when r.rentdate is not null then '우량회원'
        when r.rentdate is null then '불량회원'
    end as 종류
from tblMember m
    left outer join tblRent r
        on m.seq = r.member
            order by 종류 desc, name asc;
-- 어떤 비디오가 몇번 빌려갔는지?
select
    v.name,
    count(r.rentdate) as 대여횟수
from tblVideo v
    left outer join tblRent r
        on v.seq = r.video
            group by v.name
                order by count(r.rentdate) desc, v.name asc;

셀프 조인, self join
-- 직원테이블
-- 테이블 생성
create table tblSelf(

    seq number primary key, -- 직원번호(PK)
    name varchar2(30) not null, -- 직원명
    department varchar2(50) null, -- 부서명
    super number null references tblSelf(seq) -- 상사번호(FK), 자기참조
    
);

-- 데이터 
insert into tblSelf values (1,'홍사장', null, null);
insert into tblSelf values (2,'김부장', '영업부', 1);
insert into tblSelf values (3,'이과장', '영업부', 2);
insert into tblSelf values (4,'정대리', '영업부', 3);
insert into tblSelf values (5,'최사원', '영업부', 4);
insert into tblSelf values (6,'박부장', '개발부', 1);
insert into tblSelf values (7,'하과장', '개발부', 6);

select * from tblSelf;


-- 직원명, 소속부서, 상사명을 가져오시오.
-- 재귀 형태
-- 홍사장 미포함
select
    s1.name as "직원명",
    s1.department as "소속부서",
    s2.name as "상사명"
from tblSelf s1 -- 직원(부하)
    inner join tblSelf s2 -- 상사
        on s1.super = s2.seq; -- 중요 ********
        

-- 홍사장 포함
select
    s1.name as "직원명",
    s1.department as "소속부서",
    s2.name as "상사명"
from tblSelf s1 -- 직원(부하)
    left outer join tblSelf s2 -- 상사
        on s1.super = s2.seq; -- 중요 ********

전체 외부 조인, full outer join
select * from tblMen;
select * from tblWomen;

-- 커플인 남자와 여자를 가져오세요. -> 솔로는 안가져옴
select
    m.name as 남자, w.name as 여자
from tblMen m
    inner join tblWomen w
        on m.couple = w.name;
        
        
-- 모든 남자(outer join) + 여자친구가 있으면 여자친구 이름도 같이
select
    m.name as 남자, w.name as 여자
from tblMen m
   left outer join tblWomen w
        on m.couple = w.name;
        
        
 -- 모든 여자(outer join) + 남자친구가 있으면 남자친구 이름도 같이       
select
    m.name as 남자, w.name as 여자
from tblMen m
   right outer join tblWomen w
        on m.couple = w.name;        
        
        
-- 모든 남자 + 모든 여자 + 커플이 있으면 커플이름도 같이
select
    m.name as 남자, w.name as 여자
from tblMen m
   full outer join tblWomen w
        on m.couple = w.name
            order by m.name asc;             
profile
모르면 괴롭고 알면 즐겁다.

0개의 댓글

관련 채용 정보