----에서 쿼리 요구 사항이 있습니다. CONNECT BY
으로 해결하려고하지만 필요한 결과를 얻지 못하는 것 같습니다.여러 가능한 열 일치에서 Oracle Self-Join - CONNECT BY?
표 (간체) :
create table CSS.USER_DESC (
USER_ID VARCHAR2(30) not null,
NEW_USER_ID VARCHAR2(30),
GLOBAL_HR_ID CHAR(8)
)
-- USER_ID is the primary key
-- NEW_USER_ID is a self-referencing key
-- GLOBAL_HR_ID is an ID field from another system
사용자 데이터 (datafeeds)의 두 가지 소스가 있습니다 ... 나는 정보를 업데이트 할 때 둘 중 하나의 실수를 감시해야합니다.
시나리오 :
- 및 언젠가 나중에 돌아온다. HR이 이전 사용자 ID를 보내지 않아 계정을 연결할 수 없습니다.
- 시스템이 망가졌으며 이전 레코드에 새 사용자 ID가 설정되지 않았습니다.
- 데이터는 I가 동일한 사용자는 다음과 알 필요가 수백 다른 방법
ROOTUSER NUMROOTS NODELEVEL ISLEAF USER_ID NEW_USER_ID GLOBAL_HR_ID USERTYPE LAST_NAME FIRST_NAME
-----------------------------------------------------------------------------------------------------------------------------
EX0T1100 2 1 0 EX0T1100 EX000005 CONTRACTOR VON DER HAAVEN VERONICA
EX0T1100 2 2 1 EX000005 00126121 EMPLOYEE HAAVEN, VON DER VERONICA
GL110456 1 1 1 GL110456 00126121 EMPLOYEE VONDERHAAVEN VERONICA
EXOT1100
및 EX000005
은 NEW_USER_ID
필드에 의해 적절하게 연결되어 있습니다. 글로벌 HR ID가 있기 전에 이름이 변경되었으므로 EX0T1100
에는 이름이 없습니다. EX000005
에 새 사용자 ID 인 'GL110456'이 부여되었으며 둘은 동일한 글로벌 HR ID를 사용하여 연결됩니다.
데이터 정리는 옵션이 아닙니다.
지금까지 쿼리 : 나는 다양한 CONNECT BY
절을 시도했습니다
select connect_by_root cud.user_id RootUser,
count(connect_by_root cud.user_id) over (partition by connect_by_root cud.user_id) NumRoots,
level NodeLevel, connect_by_isleaf IsLeaf, --connect_by_iscycle IsCycle,
cud.user_id, cud.new_user_id, cud.global_hr_id,
cud.user_type_code UserType, ccud.last_name, cud.first_name
from css.user_desc cud
where cud.user_id in ('EX000005','EX0T1100','GL110456')
-- Using this so I don't get sub-users in my list of root users...
-- It complicates the matches with GLOBAL_HR_ID, however
start with cud.user_id not in (select cudsub.new_user_id
from css.user_desc cudsub
where cudsub.new_user_id is not null)
connect by nocycle (prior new_user_id = user_id);
,하지만 그들 중 누구도 확실히 맞다 :
-- As a multiple CONNECT BY
connect by nocycle (prior global_hr_id = global_hr_id)
connect by nocycle (prior new_user_id = user_id)
-- As a compound CONNECT BY
connect by nocycle ((prior new_user_id = user_id)
or (prior global_hr_id = global_hr_id
and user_id != prior user_Id))
UNIONing이 CONNECT BY 쿼리가 작동하지 않습니다 ... 나는 레벨링을 얻지 못했습니다.
다음은 내가보고 싶은 것입니다 ... 나는 별개로 사용해야하고 하위 쿼리로 사용해야하는 결과 세트는 괜찮습니다. ROOTUSER 열에있는 세 명의 사용자 ID 중 하나라도 사용해도 괜찮습니다 ... 나는 단지 그들이 동일한 사용자임을 알아야합니다.
ROOTUSER NUMROOTS NODELEVEL ISLEAF USER_ID NEW_USER_ID GLOBAL_HR_ID USERTYPE LAST_NAME FIRST_NAME
-----------------------------------------------------------------------------------------------------------------------------
EX0T1100 3 1 0 EX0T1100 EX000005 CONTRACTOR VON DER HAAVEN VERONICA
EX0T1100 3 2 1 EX000005 00126121 EMPLOYEE HAAVEN, VON DER VERONICA
EX0T1100 3 (2 or 3) 1 GL110456 00126121 EMPLOYEE VONDERHAAVEN VERONICA
아이디어가 있습니까?
업데이트
니콜라스, 당신의 코드는 ... 아주 많이 바른 길처럼 보이는 global_hr_id
가 null의 경우 순간의 lead(user_id) over (partition by global_hr_id)
거짓 안타를 가져옵니다. 예를 들어 :
USER_ID NEW_USER_ID CHAINNEWUSER GLOBAL_HR_ID LAST_NAME FIRST_NAME
FP004468 FP004469 AARON TIMOTHY
FP004469 FOONG KOK WAH
나는 종종 파티션에 별도의 기록과 같은 널 (null)을 치료하기 위해 싶었던,하지만 난 ignore nulls
작품을 만들 수있는 방법을 찾은 적이 없다. 이것은 내가 원했던 것입니다 :
decode(global_hr_id,null,null,lead(cud.user_id ignore nulls) over (partition by global_hr_id order by user_id)
...하지만 더 좋은 방법이 있어야합니다. 필자는 본격적인 사용자 데이터 (약 4 만 명의 사용자)에 대한 쿼리를 아직 완료하지 못했습니다. global_hr_id
및 new_user_id
모두 색인이 생성됩니다. 약 750 초 후에
업데이트
쿼리 반환 ... 긴하지만, 관리. 그것은 루트에서 2 레벨 히트를 필터링하는 좋은 방법이 없기 때문에 93k 레코드를 반환합니다 - 당신은 start with global_hr_id is null
입니다.하지만 불행히도, 항상 그런 것은 아닙니다. 나는 그것들을 걸러 낼 수있는 방법에 대해 좀 더 생각해야 할 것입니다.
이전에 더 복잡한 시작 절을 추가하려고 시도했지만 이전에는 < 1 초 ... 같이 실행하면 90 분이 소요됩니다. <
도와 주셔서 다시 한 번 감사드립니다 ...이 문제에 대해 다시 생각해보십시오.
우와. 나는 그렇게 가치가 없다. 지금 이걸 가지고 놀고 있어요 ... 임시 테이블 공간이 부족해서 실행하려고 합니다만, 이걸로 작동시켜야한다고 생각합니다. 감사합니다! –
추신 : 완전히 대표적인 데이터 세트를 찾는 것은 어렵습니다 ... 그 사건을 작동시킬 수 있다면, 나는 다른 사람들의 대부분이 일치한다고 생각합니다. 확실한지 테스트 할 것입니다. –
더 많은 정보가 담긴 업데이트를 올리십시오 ... 저에게 주신 내용으로 계속 게임하십시오. –