오라클 CASE WHEN 여러 테이블 이용가능한가요? 0 9 6,324

by 냉동닭 [SQL Query] CASE WHEN 테이블 [2018.06.07 15:07:45]


안녕하세요 쿼리왕초보에요

 

다름 아니라 CASE WHEN 구문을 이용해서 조건에 맞는 데이터를 가져오려고 하는데요

 

CASE WHEN 구문은 1개 테이블에서의 조건절에 맞는 데이터를 출력하잖아요

 

그런데 저는 여러개의 테이블들에서 CASE WHEN을 쓰고 싶은데 쓸 수 있는건가요?

 

문제) 초등학생테이블(A), 중학생테이블(B), 고등학생테이블(C)가 있다고 가정할 때, 학생번호는 초중고 통합해서 발급받는다고하면 학번이 1~6까지의 조건은 A테이블에서, 학번 7~9는 B테이블에서, 학번 10~12는 C테이블에서 이름을 가져오는 것을 CASE WHEN구문으로 사용 가능 할까요?

예) 테이블정정보 - 학생테이블(학번, 이름)

     컬럼정보 - 학번(앞자리가 1~6까진 초등학생, 7~9는 중학생, 10~12까진 고등학생)

 

질문도 두서없이 써서 읽으시는 분들이 헷갈릴 것 같네요..

답변 부탁드리겠습니다.

by 마농 [2018.06.07 15:31:42]

학생번호가 통합 번호인데... 학년별로 앞자리가 틀리다는 것은 모순이네요.
앞자리가 10~12 처럼 두자리가 되는 것도 이상하구요.
말로 설명하지 마시고 예시 자료를 가지고 질문해 주세요.(원본 대비 결과표)


by 아발란체 [2018.06.07 15:34:00]

당연히 쿼리로 풀이를 하여 인덱스 태워 빠르게 조회하는 것도 가능하나 소스 가독성 측면에서

쿼리가 아닌 소스상에서(=비지니스 로직) 학번 앞자리를 보고 분기하는 것이 바람직 할 것 같습니다.


by 아발란체 [2018.06.07 15:40:47]

근데..

초등학교 일학년 학번이 1로 시작하여 "110123"이란 학번을 가진다면

고등학교 이학년 학번이 11로 시작하여 "111232"이란 학번이 되면

앞 두자리로 이게 초딩인지 고딩인지 구분 할 수 있을까용?

그렇다고 학번 뒤에 0을 넣자니.. 앞2자리 짜름 초딩1학년 10이나 고딩1학년 10이나.. 같아 질 것 같고.. @.@)/


by 마농 [2018.06.07 16:21:59]

통합 학번의 의미를 제가 오해한것 같네요?
- 한 학생이 하나의 학번으로 전학년을 다닌다는 의미로 해석했는데 아닌 듯 하군요?
- 한 학생은 매 학년마다 새로운 학번을 부여 받고, 그걸 하나의 테이블에서 통합 관리한다는 의미인 듯 하네요?
- 학번의 앞 두자리가 학년을 의미한다고 가정하면... ('01' = 1학년)
 

-- 1. Case 문을 이용하는 방법 --
SELECT m.학번
     , CASE WHEN SUBSTR(m.학번, 1, 2) IN ('01','02','03','04','05','06') THEN a.이름
            WHEN SUBSTR(m.학번, 1, 2) IN ('07','08','09')                THEN b.이름
            WHEN SUBSTR(m.학번, 1, 2) IN ('10','11','12')                THEN c.이름
             END 이름
  FROM 학생통합 m
     , 초등학생 a
     ,   중학생 b
     , 고등학생 c
 WHERE a.학번(+) = CASE WHEN SUBSTR(m.학번, 1, 2) IN ('01','02','03','04','05','06') THEN m.학번 END
   AND b.학번(+) = CASE WHEN SUBSTR(m.학번, 1, 2) IN ('07','08','09')                THEN m.학번 END
   AND c.학번(+) = CASE WHEN SUBSTR(m.학번, 1, 2) IN ('10','11','12')                THEN m.학번 END
;
-- 2. 굳이 Case 문을 쓰지 않아도 될 듯.(어차피 학번이 겹칠일은 없으므로)
SELECT m.학번
     , COALESCE(a.이름, b.이름, c.이름) 이름
  FROM 학생통합 m
     , 초등학생 a
     ,   중학생 b
     , 고등학생 c
 WHERE m.학번 = a.학번(+) 
   AND m.학번 = b.학번(+) 
   AND m.학번 = c.학번(+)
;

 


by 냉동닭 [2018.06.07 20:49:17]

감사합니다 테이블을 여러개를 동시에 가져오면 되는 간단한 걸 WHEN절에서 끙끙거렸네요

덕분에 문제 해결하고 갑니다!

 


by 아발란체 [2018.06.07 16:30:00]

CASE문 다양성만 본다면 

WITH 초딩테이블 AS (
    SELECT '01231123' AS 학번, '일학년' AS 성명 FROM DUAL UNION ALL
    SELECT '02231123' AS 학번, '이학년' AS 성명 FROM DUAL UNION ALL
    SELECT '03231123' AS 학번, '삼학년' AS 성명 FROM DUAL UNION ALL
    SELECT '04231123' AS 학번, '사학년' AS 성명 FROM DUAL UNION ALL
    SELECT '05231123' AS 학번, '오학년' AS 성명 FROM DUAL UNION ALL
    SELECT '06231123' AS 학번, '육학년' AS 성명 FROM DUAL 
), 중딩테이블 AS (
    SELECT '07311123' AS 학번, '중일학' AS 성명 FROM DUAL UNION ALL
    SELECT '321123' AS 학번, '중이학' AS 성명 FROM DUAL UNION ALL
    SELECT '09331123' AS 학번, '중삼학' AS 성명 FROM DUAL 
), 고딩테이블 AS (
    SELECT '10311123' AS 학번, '고일학' AS 성명 FROM DUAL UNION ALL
    SELECT '11314123' AS 학번, '고이학' AS 성명 FROM DUAL UNION ALL
    SELECT '122331123' AS 학번, '고삼학' AS 성명 FROM DUAL
)
SELECT
    학번,
    CASE
        WHEN 학번 < 7 THEN '초딩'
        WHEN 학번 < 10 THEN '중딩'
        ELSE '고딩'
    END
FROM (
    SELECT
        TO_NUMBER(SUBSTR(학번, 1, 2)) AS 학번
    FROM (
        SELECT * FROM 초딩테이블 UNION ALL
        SELECT * FROM 중딩테이블 UNION ALL
        SELECT * FROM 고딩테이블 
    )
);

 


by 냉동닭 [2018.06.07 20:50:31]

감사합니다! 답변 정성스럽게 달아주셔서 쉽게 이해할 수 있었습니다! 고맙습니다~


by 아발란체 [2018.06.07 16:42:07]

조건절에 학번을 입력하여 적합한 테이블을 찾을 때

SELECT * FROM 초딩테이블 WHERE 1 = CASE WHEN(TO_NUMBER(SUBSTR(:학번, 1, 2)) < 7) THEN 1 ELSE 0 END AND 학번 = :학번
UNION ALL
SELECT * FROM 중딩테이블 WHERE 1 = CASE WHEN(TO_NUMBER(SUBSTR(:학번, 1, 2)) IN(7, 8, 9)) THEN 1 ELSE 0 END AND 학번 = :학번
UNION ALL
SELECT * FROM 고딩테이블  WHERE 1 = CASE WHEN(TO_NUMBER(SUBSTR(:학번, 1, 2)) > 9) THEN 1 ELSE 0 END AND 학번 = :학번;

 


by 아발란체 [2018.06.07 16:54:42]

이 경우 학번이 인덱스 경우

UNIQUE SCAN > BY INDEX ROWID 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입