update쿼리 질문드립니다. 0 14 4,107

by 성이 join update [2014.09.03 16:13:25]


어제도 질문드렸는데 비슷한 질문 또 드립니다 

쿼리가 너무 어렵네요 ㅠㅠ

두개의 테이블을 join해서 한컬럼을 update하는것 입니다.

그런데 a테이블, b테이블을 비교해서 조건이 맞으면 b테이블의 특정 컬럼내용을 a테이블의 컬럼에 복사하는 것인데

둘을 비교할때 b테이블에서 같은 조건이 2개 이상 나오는게 있어서 에러가 납니다.

이걸 중복제거를 해야하는데 잘 안되서요

UPDATE TBL_MEMBER_TEST B 
       SET B.REQ_NO = 
       (SELECT DISTINCT A.REQ_TEMP 
         FROM EDU_TARGET_T_NEW_TEST A 
        WHERE b.RES_NO = a.REQ_NO 
              AND b.MBR_NM = a.NAME 
              AND SUBSTR(b.birthday,3,6) = a.BIRTHDAY 
              AND b.REQ_NO IS NULL
       ) 
 WHERE EXISTS 
       (SELECT DISTINCT 1 
         FROM EDU_TARGET_T_NEW_TEST A 
        WHERE b.RES_NO = a.REQ_NO 
              AND b.MBR_NM = a.NAME 
              AND SUBSTR(b.birthday,3,6) = a.BIRTHDAY 
              AND b.REQ_NO IS NULL
       );

-----------------------------------------------------------------------------------

UPDATE TBL_MEMBER_TEST b 
       SET req_no = 
       (SELECT DISTINCT a.req_temp 
         FROM EDU_TARGET_T_NEW_TEST a 
        WHERE b.RES_NO = a.REQ_NO 
              AND b.MBR_NM = a.NAME 
              AND SUBSTR(b.birthday,3,6) = a.BIRTHDAY 
              AND b.REQ_NO IS NULL 
       )

 

이렇게 두가지로 해보았는데 둘다.. 

ORA-01427: single-row subquery returns more than one row

에러가 납니다.. 간단한거 같은데 이러니 참... 어떻게 하면 좋을가요;;;

by 우리집아찌 [2014.09.03 16:41:14]

서브쿼리에 중복 문제가 아니라 두개 이상이 로우가 생기는건데

먼저 어떤데이터를 UPDATE 할지 요건부터 정리하셔야할것같네요..

그냥 아무거나 넣을래 이러시면 MAX() , MIN() 등을 사용하시면 됩니다.

 


by 마농 [2014.09.03 16:48:29]

DISTINCT 는 같은 값에 대한 중복 제거죠.

다른 값이 여러개 조회된다면 중복제거되지 않습니다.

아찌님 말씀대로 1건 선택의 기준을 정립하셔야 합니다.

 - 최소 MIN

 - 최대 MAX

 - 조회되는 대로 한건만 ROWNUM=1

 - 가장 나중에 등록된거

 - 가장 먼저 등록된거

 - 가장 중요도가 높은거


by 성이 [2014.09.03 17:08:14]

답변들 감사드립니다. 

제가 이해가 잘 안가네요 ㅠㅠ 일단 두개 이상로우가 생기는건 똑같은 정보가 생기는 겁니다.. 

한마디로 동일인물이 2개이상 검색이 되는것이죠 그래서 DISTINCT 로 할려는데 잘 안되네요;;

글구 max나 min 같은 어디다가 써야하는지;; 문자열인데도 저게 먹히나요?;;;

등록순서나 그런건 테이블에 정보가 없습니다 t_no라는 시쿼스가 있긴한데 이게 간혹 중복도 있구요

조회되는 대로 한건만 ROWNUM=1 이란건 어떻게 해야 하는지요 제가 쿼리 완전 초보라서 ㅠㅠ

 


by 마농 [2014.09.03 17:26:53]

동일 인물(res_no, mbr_nm, birthday)에 대해서 값(req_temp)까지 동일한건 아니죠.
값이 다른거죠.
이렇게 여러개 나온 req_temp 값중에 어떤 값을 선택할지가 정해져야 하는 것입니다.


지금 이해를 못한 상태로 MIN, MAX 를 적용하여 에러를 피해가는게 능사가 아닙니다.
왜 중복이 발생하는지?
중복이 발생하지 않도록 하는 다른 추가 조건은 없는지?
중복이 발생할 수밖에 없는 상황이라면? 어떤 값을 선택해야 할지?
여러가지 고민이 필요합니다.
이는 SQL 과는 전혀 상관이 없는 비지니스 로직 부분입니다.

UPDATE tbl_member_test b 
   SET b.req_no = (SELECT MIN(a.req_temp)
                     FROM edu_target_t_new_test a 
                    WHERE a.req_no   = b.res_no 
                      AND a.name     = b.mbr_nm
                      AND a.birthday = SUBSTR(b.birthday, 3, 6)
                   ) 
 WHERE b.req_no IS NULL
;

 


by 성이 [2014.09.03 17:52:20]

감사드립니다..

후~~ SQL은 너무 헷갈리네요 ㅠㅠ

좀더 생각을 많이 해봐야겠습니다..

조언 감사드립니다 ^^


by 성이 [2014.09.03 19:19:48]

아~ 제가 헷갈리긴 했는데요 답변해주신 거에요

동일 인물(res_no, mbr_nm, birthday)에 대해서 값(req_temp)까지 동일합니다..

한마디로 모든 값이 일치하는 인물이 중복되서 들어가 있습니다.

 


by 마농 [2014.09.04 08:16:38]

지금 하신 말에 확신이 있나요? 검증을 해보셨나요?
왜? 에러메시지가 알려주는 부분이나, 도움을 드리고자 하는 답글들을 믿지 못하시고
검증도 없이 본인의 생각이 옳다고만 생각하시는지 모르겠네요.

-- 중복 자료 찾기
SELECT req_no, name, birthday
     , COUNT(*) cnt
     , COUNT(DISTINCT req_temp) cnt_distinct
     , wm_concat(DISTINCT req_temp) req_temp_list
  FROM edu_target_t_new_test
 GROUP BY req_no, name, birthday
 HAVING COUNT(DISTINCT req_temp) > 1
;

 


by 성이 [2014.09.04 11:01:44]

으윽~ 답변해주셨는데 기분이 나쁘셨다면 죄송합니다. ㅠㅠ

일단 저두 이 상황이 참 애매해서요

이런저런 상황을 파악 후 정확하게 질문을 드려야 하는데 쿼리 실력이 미천하다보니 

그렇지 못하서 답변 주신분들의 말이 맞아도 제가 이해를 잘 못하는거 같습니다..ㅠㅠ

글구 서비스 되고있는 오라클이 9i라 써주신 wm_concat 은 10g부터 지원하는지 실행이 안되네요;

edu_target_t_new 테이블에서 임의로 뽑아 보았는데 이렇게 보면 req_temp가 동일합니다;;

전 위 테이블과 회원테이블 매칭해서 동일 인물이면 req_temp를 회원테이블 req_no에 넣는거인데

중복되는 데이터가 나오니 에러가 난다고 생각을 했습니다;; 

comp_date는 어떤건 2014/05/05.. 2014-05-05 . 14-05-05. 1455 이런식으로 뒤죽박죽 들어가 있는상태라 비교나 체크를 할 데이터가 안될꺼 같습니다.

t_no이 그나마 체크할만한데;; 이게 저것도 중복값이 가끔 있어서요;;

그래도 답변 본후 t_no로 한번 체크 해보는데 제가 잘못해서 겠지만 에러만 나고  안되더군요;;;

위 테이블은 몇년전부터 프로그램에서 자동으로 넣는게 아니라 사람이 입력하는거라 좀 데이터가 뒤죽박죽 박죽이라 들었습니다..;;

데이터를 넣을때 기존인물 검색을 하고 있다면 안넣어도 되고 없다면 넣어야 하는데 그냥 무조건

insert시켰다고 하더라고요;;

원래는 단순히 회원테이블과 위 테이블에 같은 주민등록번호가 있나 없나 체크하는 거였는데

이번에 개인정보법이 바뀌면서 기존 정보들을 바탕으로 새로운 식별번호로 매칭하는데 참 애매하네요;;

간단한거 같은데 실제로 해볼라면 일반 자바 코딩처럼 머리속대로 잘 안되니 답답하기만 하네요;;;

 


by 마농 [2014.09.04 11:14:12]

wm_concat 부분만 빼고 실행해 보세요.


by 성이 [2014.09.04 11:18:54]

데이터가 없다고 나옵니다.


by 마농 [2014.09.04 11:24:58]

데이터가 없다라???
그렇다면 req_temp IS NULL 인 자료가 있을지도 모르겠네요.
COUNT 에서는 NULL 이 제외되니까요.
널인 것과 아닌것 이렇게 2개 행이 추출된 듯 하네요.

-- 중복 자료 다시 찾기
SELECT req_no, name, birthday
     , COUNT(*) cnt
     , COUNT(DISTINCT NVL(req_temp, 'x')) cnt_distinct
  FROM edu_target_t_new_test
 GROUP BY req_no, name, birthday
 HAVING COUNT(DISTINCT NVL(req_temp, 'x')) > 1
;

 

 


by 성이 [2014.09.04 11:40:43]

아~네 말씀하신것처럼 null값이 있네요

이렇게하니 정보들이 많이 나옵니다;;


by 마농 [2014.09.04 11:46:49]

널만 조건에서 제외하면 아무 문제 없겠네요.


by 성이 [2014.09.04 12:25:45]

신경써주시고

답변 감사합니다 ^^

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