쿼리 질문드립니다. 0 6 584

by 고쿠 [2020.07.23 17:25:45]


파라미터로 'A,AA,AB,AC' 이러한 등급을 받는데

WHERE GRADE IN (REGEXP_REPLACE(REGEXP_REPLACE('A,AA,AB,AC', '^\|$|,', ''','''), '^|$', ''''))

위와같이 조건절에 넣으면 값이 안나옵니다.

WHERE GRADE IN ('A','AA','AB','AC')

위와같이 만들어져서 데이터가 조회될거같은데... 무엇이 잘못된걸까요??

고수님들의 지도 부탁드립니다.

by 우리집아찌 [2020.07.23 17:36:40]
저렇게 하시면 WHERE GRADE IN (''A','AA','AB','AC'') <= 이렇게 인식됩니다.

-- 아래처럼 변경해주세요.
WITH T AS (
SELECT REGEXP_SUBSTR('A,AA,AB,AC','[^,]+',1,LEVEL) V
  FROM DUAL CONNECT BY LEVEL <= 4 
) , T2 AS (

SELECT 'A' GRADE FROM DUAL UNION ALL
SELECT 'AA' FROM DUAL UNION ALL
SELECT 'AB' FROM DUAL UNION ALL
SELECT 'AD' FROM DUAL 
)

SELECT * FROM T2 
WHERE GRADE IN ( SELECT V FROM T )

 

 

 

 


by 고쿠 [2020.07.23 20:50:52]

답변감사드립니다.

등급이 15개정도 되는데 사용자가 선택한만큼 파라메터로 받아서

IN 절에 넣어줘야하는데 파라메타로 받은 값을 'A','AA','AB','AC' 이렇게 바로 변환할수는 없을까요??


by 춘 [2020.07.23 23:01:06]
SELECT
    REGEXP_REPLACE('A,AA,AB,AC', '([^,]+)', CHR(39)||'\1'||CHR(39)) AS t1
    , REGEXP_REPLACE('A,AA,AB,AC,AD,AE,AF', '([^,]+)', CHR(39)||'\1'||CHR(39)) AS t2
FROM dual
;

 


by 마농 [2020.07.24 08:48:57]

IN ('A','AA','AB','AC') 이 구문은 4개의 값이 비교되는 구문이고
IN (REGEXP_REPLACE(REGEXP_REPLACE('A,AA,AB,AC', '^\|$|,', ''','''), '^|$', ''''))
이 구문은 하나의 값을 지지고 볶아 결국 하나의 값을 만들어 내서 비교하는 구문입니다.
하나의 값 안에 컴마나 따옴표를 넣는다고 여러개의 값이 되지는 않습니다.
여러개의 값이 되려면 우리집아찌님의 방식처럼 행으로 복제하여 나누는 방법이 있구요.
원하시는 것처럼 아예 4개의 값으로 분리하려면?
최대 개수 만큼, 즉, 15개의 값으로 나누면 되긴 하겠네요.

SELECT *
  FROM t
 WHERE grade IN ( REGEXP_SUBSTR(v_param, '[^,]+', 1,  1)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  2)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  3)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  4)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  5)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  6)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  7)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  8)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1,  9)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1, 10)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1, 11)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1, 12)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1, 13)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1, 14)
                , REGEXP_SUBSTR(v_param, '[^,]+', 1, 15)
                )
;

이렇게까지 해야 할지?
성능이 크게 나쁘지 않다면?
그냥 문자 비교를 하는 방법도 있습니다.

SELECT *
  FROM t
 WHERE INSTR(','||v_param||',', ','||grade||',') > 0
;

대용량에 인덱스를 이용해야만 하는 상황이라면?
우리집아찌님 방식을 써야 할 것 같긴한데.
이게 인덱스를 잘 탈 수 있을지는 실행계획 확인이 필요합니다.
15개 정도로 개수가 고정이라면?
조금은 무식해 보이더라도 위에 제가 제시한 방법이 나을 수도 있습니다.


by 춘 [2020.07.24 21:38:51]

역시.

고수분들의 쿼리와 설명

많이 참조하며, 배우고 갑니다.


by 고쿠 [2020.07.24 21:44:35]

우리집아찌님 방식을 사용해서 해결하였습니다.

춘님, 마농님 답변도 적용해보면서 공부해보겠습니다.

감사합니다.^^

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