VALUE 를 정하는 조건 (조건 테이블) 이 있고, 조건에 따라 데이터 테이블의 VALUE가 정해집니다.
DEFAULT 가 존재하고, 조건 테이블의 컬럼들을 순차 체크합니다.
케이스를 예시로 보자면
1. 먼저 이름을 체크하고, 이름이 박__ 이 아닌 경우 DEFAULT 인 값 5 를 받습니다.
2. 위 (1) 을 제외한
박__ 인 경우 그 다음 순서인 성별을 체크하고, 성별이 남 이 아닌경우 값 10 을 받습니다.
3. 위 (1), (2) 에 포함되지 않은
박__ 인 경우 그 다음 순서인 나이, 키, 몸무게를 순차적으로 검증합니다.
데이터 TABLE 생성 후 조건에 따라 데이터들에 값을 UPDATE 해주려고 합니다.
저 테이블을 활용해서 순차적으로 처리하고 제외하는 방법을 어떤식으로 접근해야할지 생각해봐도 감이 안와서 도움 요청드립니다..
RULE 이 맞는 값이 DATA의 값 에 들어가야합니다.. 원하는 값은 들어가야 하는 값을 적어두었습니다..
RULE 테이블 ( DEFAULT 값이 있고, ADD 되는 룰에 따라 값이 정해집니다. '-' 는 ALL 입니다. )
이름 | 성별 | 나이 | 키 | 몸무게 | 값 | |
___ | - | - | - | - | 5 | DEFAULT |
박__ | - | - | - | - | 10 | ADD |
박__ | 남 | - | - | - | 20 | ADD |
박__ | 남 | - | 150 | - | 30 |
ADD |
데이터 테이블 ( 이 테이블에 VALUE 를 RULE 에 맞는 값으로 UPDATE 하는것이 목적입니다. )
이름 | 성별 | 나이 | 키 | 몸무게 | VALUE | 원하는 VALUE |
박길동 | 남 | 10 | 150 | 50 | 0 | 30 |
박네모 | 남 | 10 | 160 | 50 | 0 | 20 |
박하나 | 여 | 10 | 150 | 50 | 0 | 10 |
정길동 | 남 | 10 | 150 | 50 | 0 | 5 |
체크 컬럼 순서 테이블
컬럼 | 순서 |
이름 | 1 |
성별 | 2 |
나이 | 3 |
키 | 4 |
몸무게 | 5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | WITH RULE AS ( SELECT '___' AS 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 5 값, 'DEFAULT' INIT FROM DUAL UNION ALL SELECT '박__' AS 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 10 값 , 'CHECK' INIT FROM DUAL UNION ALL SELECT '박__' AS 이름, '남' 성별, '-' 나이, '-' 키, '-' 몸무게, 20 값 , 'CHECK' INIT FROM DUAL UNION ALL SELECT '박__' AS 이름, '남' 성별, '-' 나이, '150' 키, '-' 몸무게, 30 값 , 'CHECK' INIT FROM DUAL ), DATA AS ( SELECT '박길동' AS 이름, '남' 성별, '10' 나이, '150' 키, '50' 몸무게, 0 값, '30' 원하는값 FROM DUAL UNION ALL SELECT '박네모' AS 이름, '남' 성별, '10' 나이, '160' 키, '50' 몸무게, 0 값, '20' 원하는값 FROM DUAL UNION ALL SELECT '박하나' AS 이름, '여' 성별, '10' 나이, '150' 키, '50' 몸무게, 0 값, '10' 원하는값 FROM DUAL UNION ALL SELECT '정길동' AS 이름, '남' 성별, '10' 나이, '150' 키, '50' 몸무게, 0 값, '5' 원하는값 FROM DUAL ), SEQ AS ( SELECT '이름' 컬럼, 1 순서 FROM DUAL UNION ALL SELECT '성별' 컬럼, 2 순서 FROM DUAL UNION ALL SELECT '나이' 컬럼, 3 순서 FROM DUAL UNION ALL SELECT '키' 컬럼, 4 순서 FROM DUAL UNION ALL SELECT '몸무게' 컬럼, 5 순서 FROM DUAL ) SELECT * FROM SEQ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | WITH rule AS ( SELECT '___' 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 5 값, 'DEFAULT' init FROM dual UNION ALL SELECT '박__' , '-' , '-' , '-' , '-' , 10, 'CHECK' FROM dual UNION ALL SELECT '박__' , '남' , '-' , '-' , '-' , 20, 'CHECK' FROM dual UNION ALL SELECT '박__' , '남' , '-' , '150' , '-' , 30, 'CHECK' FROM dual ) , data AS ( SELECT '박길동' 이름, '남' 성별, '10' 나이, '150' 키, '50' 몸무게 FROM dual UNION ALL SELECT '박네모' , '남' , '10' , '160' , '50' FROM dual UNION ALL SELECT '박하나' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '정길동' , '남' , '10' , '150' , '50' FROM dual UNION ALL SELECT '박군' , '남' , '10' , '150' , '50' FROM dual ) SELECT a.이름 , a.성별 , a.나이 , a.키 , a.몸무게 , MAX (b.값) 값 FROM data a LEFT OUTER JOIN rule b ON a.이름 LIKE b.이름 AND a.성별 LIKE REPLACE (b.성별 , '-' , '%' ) AND a.나이 LIKE REPLACE (b.나이 , '-' , '%' ) AND a.키 LIKE REPLACE (b.키 , '-' , '%' ) AND a.몸무게 LIKE REPLACE (b.몸무게, '-' , '%' ) GROUP BY a.이름 , a.성별 , a.나이 , a.키 , a.몸무게 ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | WITH rule AS ( SELECT '수학과' CLASS, '___' 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 5 값, 'DEFAULT' init FROM dual UNION ALL SELECT '체육과' CLASS, '___' 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 99 값, 'DEFAULT' init FROM dual UNION ALL SELECT '체육과' CLASS, '정__' 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 22 값, 'CHECK' init FROM dual UNION ALL SELECT '수학과' CLASS, '박__' , '-' , '-' , '-' , '-' , 10, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박하_' , '-' , '-' , '-' , '-' , 11, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박__' , '남' , '-' , '-' , '-' , 20, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박__' , '남' , '-' , '150' , '-' , 30, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '정__' , '여' , '-' , '150' , '-' , 50, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '정__' , '-' , '-' , '-' , '20' , 33, 'CHECK' FROM dual ) , data AS ( SELECT '수학과' CLASS, '박길동' 이름, '남' 성별, '10' 나이, '150' 키, '50' 몸무게 FROM dual UNION ALL SELECT '수학과' CLASS , '박네모' , '남' , '10' , '160' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '박하나' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '박미나' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '정길동' , '남' , '10' , '150' , '50' FROM dual UNION ALL SELECT '체육과' CLASS , '정여자' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '체육과' CLASS , '남여자' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '박군' , '남' , '10' , '150' , '50' FROM dual ) SELECT a.CLASS , a.이름 , a.성별 , a.나이 , a.키 , a.몸무게 , MAX (b.값) 값 FROM data a LEFT OUTER JOIN rule b ON a.CLASS LIKE B.CLASS AND A.이름 LIKE B.이름 AND a.성별 LIKE REPLACE (b.성별 , '-' , '%' ) AND a.나이 LIKE REPLACE (b.나이 , '-' , '%' ) AND a.키 LIKE REPLACE (b.키 , '-' , '%' ) AND a.몸무게 LIKE REPLACE (b.몸무게, '-' , '%' ) GROUP BY a.class , a.이름 , a.성별 , a.나이 , a.키 , a.몸무게 ; |
위 코드대로 실행하면
체육과의 남여자 는 99의 값.
체육과의 정여자 는 22의 값이
나와야 한다고 생각하는데 이름 에서 조건이 먹지않는것 같습니다. 컬럼 순서적인 문제일까요?
감사합니니다 마농님. 다른 업무로 너무 늦게 왔습니다..
점수라는 컬럼의 숫자는 일치 여부와 관련된 SCORE 가 아닌,
그 상황에 따른 고정된 값이 들어오는 것 입니다.
예를들어 우편번호 처럼요,,
이름이 일치하지 않는 것 이 RULE 에 99 라고 되어있다면 99 로 들어오고,
이름이 일치하는 것에 대한 RULE 이 1 이라고 되어있으면 이름이 일치하는것은 1 로 들어오도록 하는 것 입니다.
어제도 다시 고민하면서 시도해보는데 어디서 멈춰버린건지 해결이 되지 않네요..
그래서 우선순위 체크하는 테이블이 필요할것같다고 생각했던것인가 싶기도 하네요
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | WITH rule AS ( SELECT '수학과' class, '___' 이름, '-' 성별, '-' 나이, '-' 키, '-' 몸무게, 5 값, 'DEFAULT' init FROM dual UNION ALL SELECT '체육과' CLASS, '___' , '-' , '-' , '-' , '-' , 99, 'DEFAULT' FROM dual UNION ALL SELECT '체육과' CLASS, '정__' , '-' , '-' , '-' , '-' , 22, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박__' , '-' , '-' , '-' , '-' , 10, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박하_' , '-' , '-' , '-' , '-' , 11, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박__' , '남' , '-' , '-' , '-' , 20, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '박__' , '남' , '-' , '150' , '-' , 30, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '정__' , '여' , '-' , '150' , '-' , 50, 'CHECK' FROM dual UNION ALL SELECT '수학과' CLASS, '정__' , '-' , '-' , '-' , '20' , 33, 'CHECK' FROM dual ) , data AS ( SELECT '수학과' class, '박길동' 이름, '남' 성별, '10' 나이, '150' 키, '50' 몸무게 FROM dual UNION ALL SELECT '수학과' CLASS , '박네모' , '남' , '10' , '160' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '박하나' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '박미나' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '정길동' , '남' , '10' , '150' , '50' FROM dual UNION ALL SELECT '체육과' CLASS , '정여자' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '체육과' CLASS , '남여자' , '여' , '10' , '150' , '50' FROM dual UNION ALL SELECT '수학과' CLASS , '박군' , '남' , '10' , '150' , '50' FROM dual ) -- 우선순위에 따라 2의 제곱 형태로 점수를 부여하는 방법 -- SELECT a.class , a.이름 , a.성별 , a.나이 , a.키 , a.몸무게 , MAX (b.값) KEEP(DENSE_RANK FIRST ORDER BY CASE WHEN a.이름 LIKE b.이름 THEN DECODE(REGEXP_COUNT(b.이름, '_' ), 0, 64 , 1, 32 , 2, 16 , 0) ELSE 0 END + DECODE(a.성별 , b.성별 , 8, 0) + DECODE(a.나이 , b.나이 , 4, 0) + DECODE(a.키 , b.키 , 2, 0) + DECODE(a.몸무게, b.몸무게, 1, 0) DESC ) AS 값 FROM data a LEFT OUTER JOIN rule b ON a.class = b.class AND a.이름 LIKE b.이름 AND a.성별 LIKE REPLACE (b.성별 , '-' , '%' ) AND a.나이 LIKE REPLACE (b.나이 , '-' , '%' ) AND a.키 LIKE REPLACE (b.키 , '-' , '%' ) AND a.몸무게 LIKE REPLACE (b.몸무게, '-' , '%' ) GROUP BY a.class , a.이름 , a.성별 , a.나이 , a.키 , a.몸무게 ; |