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 |
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
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.몸무게 ;
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 로 들어오도록 하는 것 입니다.
어제도 다시 고민하면서 시도해보는데 어디서 멈춰버린건지 해결이 되지 않네요..
그래서 우선순위 체크하는 테이블이 필요할것같다고 생각했던것인가 싶기도 하네요
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.몸무게 ;