Masz ciężkie zapytanie (wykonanie 15 minut), ale zwraca więcej wyników niż potrzebuję. Jest to zapytanie CONNECT BY i otrzymuję węzły będące potomkami w wynikach węzła głównego. Tj .:Wyłączenie wyników wyświetlanych w innej kolumnie zapytania CONNECT BY
Ted
Bob
John
Bob
John
John
Normalnie, sposób rozwiązać ten stosuje zaczynać się stanie, zazwyczaj wymagające rodzica węzła być zerowa. Ale ze względu na naturę zapytania, nie mam wartości START z wartościami, które muszę porównać, dopóki nie uzyskałem pełnego zestawu wyników. Zasadniczo próbuję podwójnie zapytać o moje wyniki, aby powiedzieć QUERY STUFF START WITH RECORDS, KTÓRE NIE SĄ W TYM STUFF.
Oto zapytanie (zbudowany z pomocą Nicholas Krasnov, tutaj: Oracle Self-Join on multiple possible column matches - CONNECT BY?):
select cudroot.root_user, cudroot.node_level, cudroot.user_id, cudroot.new_user_id,
cudbase.* -- Not really, just simplyfing
from css.user_desc cudbase
join (select connect_by_root(user_id) root_user,
user_id user_id,
new_user_id new_user_id,
level node_level
from (select cudordered.user_id,
coalesce(cudordered.new_user_id, cudordered.nextUser) new_user_id
from (select cud.user_id,
cud.new_user_id,
decode(cud.global_hr_id, null, null, lead(cud.user_id ignore nulls) over (partition by cud.global_hr_id order by cud.user_id)) nextUser
from css.user_desc cud
left join gsu.stg_userdata gstgu
on (gstgu.user_id = cud.user_id
or (gstgu.sap_asoc_global_id = cud.global_hr_id))
where upper(cud.user_type_code) in ('EMPLOYEE','CONTRACTOR','DIV_EMPLOYEE','DIV_CONTRACTOR','DIV_MYTEAPPROVED')) cudordered)
connect by nocycle user_id = prior new_user_id) cudroot
on cudbase.user_id = cudroot.user_id
order by
cudroot.root_user, cudroot.node_level, cudroot.user_id;
To daje mi wyniki o związanych użytkowników (oparte off user_id zmienia nazwę lub związane identyfikatory SAP), które wyglądają tak:
ROOT_ID LEVEL USER_ID NEW_USER_ID
------------------------------------------------
A5093522 1 A5093522 FG096489
A5093522 2 FG096489 A5093665
A5093522 3 A5093665
FG096489 1 FG096489 A5093665
FG096489 2 A5093665
A5093665 1 A5093665
Potrzebuję sposobu na odfiltruj pierwszy join (select connect_by_root(user_id)...
, aby wykluczyć FG096489
i A5093665
z listy głównej.
Najlepszy START WITH
mogę myśleć będzie wyglądać następująco (nie testowane jeszcze):
start with user_id not in (select new_user_id
from (select coalesce(cudordered.new_user_id, cudordered.nextUser) new_user_id
from (select cud.new_user_id,
decode(cud.global_hr_id, null, null, lead(cud.user_id ignore nulls) over (partition by cud.global_hr_id order by cud.user_id)) nextUser
from css.user_desc cud
where upper(cud.user_type_code) in ('EMPLOYEE','CONTRACTOR','DIV_EMPLOYEE','DIV_CONTRACTOR','DIV_MYTEAPPROVED')) cudordered)
connect by nocycle user_id = prior new_user_id)
... ale ja skutecznie wykonując moje 15 minut zapytanie dwukrotnie.
Przyjrzałem się używaniu partycji w zapytaniu, ale tak naprawdę nie ma partycji ... Chcę spojrzeć na pełny zestaw wyników new_user_ids. Zbadałem również funkcje analityczne, takie jak ranga() ... moja torba trików jest pusta.
Wszelkie pomysły?
Wyjaśnienie
Powodem nie chcę dodatkowych zapisów na liście korzeni dlatego chcę tylko jedną grupę wyników dla każdego użytkownika. I.E., jeśli Bob Smith miał w trakcie swojej kariery cztery konta (ludzie przychodzą i odchodzą często, jako pracownicy i/lub kontrahenci), chcę pracować z zestawem kont, które wszystkie należą (ed) do Boba Smitha.
Jeśli Bob przybył tutaj jako wykonawca, zamieniony na pracownika, po lewej stronie, wrócił jako kontrahent w innym kraju, a następnie odszedł/zwrócił do prawnego organu, który jest teraz w naszym systemie SAP, jego nazwa/nazwa może zmienić nazwę konta wyglądać następująco:
Bob Smith CONTRACTOR ---- US0T0001 -> US001101 (given a new ID as an employee)
Bob Smith EMPLOYEE ---- US001101 -> EB0T0001 (contractor ID for the UK)
Bob Smith CONTRACTOR SAP001 EB0T000T (no rename performed)
Bob Smith EMPLOYEE SAP001 TE110001 (currently-active ID)
w powyższym przykładzie, cztery rachunki są połączone albo new_user_id
pola, który został ustawiony, gdy użytkownik został przemianowany lub za posiadające ten sam identyfikator systemu SAP.
Ponieważ HR często nie postępuje zgodnie z procesem biznesowym, powracający użytkownicy mogą skończyć z każdym z czterech przywracanych do nich identyfikatorów. Muszę przeanalizować wszystkie identyfikatory dla Boba Smitha i powiedzieć "Bob Smith może przywrócić tylko TE110001" i wykrzyczeć błąd, jeśli próbują przywrócić coś innego. Muszę to zrobić dla ponad 90 000 rekordów.
Pierwsza kolumna "Bob Smith" jest po prostu identyfikatorem grupy powiązanych rachunków. W moim oryginalnym przykładzie używam identyfikatora użytkownika root jako identyfikatora (np. US0T0001). Jeśli używam imion/nazwisk w celu identyfikacji użytkowników, kończę na kolizjach.
Więc Bob Smith będzie wyglądać następująco:
US0T0001 1 CONTRACTOR ---- US0T0001 -> US001101 (given a new ID as an employee)
US0T0001 2 EMPLOYEE ---- US001101 -> EB0T0001 (contractor ID for the UK)
US0T0001 3 CONTRACTOR SAP001 EB0T0001 (no rename performed)
US0T0001 4 EMPLOYEE SAP001 TE110001 (currently-active ID)
... gdzie 1, 2, 3, 4 są poziomy w heirarchy.
Ponieważ wszystkie US0T0001, US001101, EB0T0001 i TE110001 są uwzględnione, nie chcę dla nich innej grupy. Ale wyniki mam teraz mają rachunki te wymienione w wielu grupach:
US001101 1 EMPLOYEE ---- US001101 -> EB0T0001 (
US001101 2 CONTRACTOR SAP001 EB0T0001
US001101 3 EMPLOYEE SAP001 TE110001
EB0T0001 1 CONTRACTOR SAP001 EB0T0001
EB0T0001 2 EMPLOYEE SAP001 TE110001
US001101 1 EMPLOYEE SAP001 TE110001
Powoduje to dwa problemy:
- Kiedy zapytanie wyniki dla identyfikatora użytkownika, otrzymuję trafień z wielu grup
- Każda grupa zgłasza inny oczekiwany identyfikator użytkownika dla Boba Smitha.
Pytałeś rozszerzonego zestawu rekordów ... oto niektóre rzeczywiste dane:
-- NumRootUsers tells me how many accounts are associated with a user.
-- The new user ID field is explicitly set in the database, but may be null.
-- The calculated new user ID analyzes records to determine what the next related record is
NumRoot New User Calculated
RootUser Users Level UserId ID Field New User ID SapId LastName FirstName
-----------------------------------------------------------------------------------------------
BG100502 3 1 BG100502 BG1T0873 BG1T0873 GRIENS VAN KION
BG100502 3 2 BG1T0873 BG103443 BG103443 GRIENS VAN KION
BG100502 3 3 BG103443 41008318 VAN GRIENS KION
-- This group causes bad matches for Kion van Griens... the IDs are already accounted for,
-- and this group doesn't even grab all of the accounts for Kion. It's also using a new
-- ID to identify the group
BG1T0873 2 1 BG1T0873 BG103443 BG103443 GRIENS VAN KION
BG1T0873 2 2 BG103443 41008318 VAN GRIENS KION
-- Same here...
BG103443 1 1 BG103443 41008318 VAN GRIENS KION
-- Good group of records
BG100506 3 1 BG100506 BG100778 41008640 MALEN VAN LARS
BG100506 3 2 BG100778 BG1T0877 41008640 MALEN VAN LARS
BG100506 3 3 BG1T0877 41008640 VAN MALEN LARS
-- Bad, unwanted group of records
BG100778 2 1 BG100778 BG1T0877 41008640 MALEN VAN LARS
BG100778 2 2 BG1T0877 41008640 VAN MALEN LARS
-- Third group for Lars
BG1T0877 1 1 BG1T0877 41008640 VAN MALEN LARS
-- Jan... fields are set differently than the above examples, but the chain is calculated correctly
BG100525 3 1 BG100525 BG1T0894 41008651 ZANWIJK VAN JAN
BG100525 3 2 BG1T0894 TE035165 TE035165 41008651 VAN ZANWIJK JAN
BG100525 3 3 TE035165 41008651 VAN ZANWIJK JAN
-- Bad
BG1T0894 2 1 BG1T0894 TE035165 TE035165 41008651 VAN ZANWIJK JAN
BG1T0894 2 2 TE035165 41008651 VAN ZANWIJK JAN
-- Bad bad
TE035165 1 1 TE035165 41008651 VAN ZANWIJK JAN
-- Somebody goofed and gave Ziano a second SAP ID... but we still matched correctly
BG100527 3 1 BG100527 BG1T0896 41008652 STEFANI DE ZIANO
BG100527 3 2 BG1T0896 TE033030 TE033030 41008652 STEFANI DE ZIANO
BG100527 3 3 TE033030 42006172 DE STEFANI ZIANO
-- And we still got extra, unwanted groups
BG1T0896 3 2 BG1T0896 TE033030 TE033030 41008652 STEFANI DE ZIANO
BG1T0896 3 3 TE033030 42006172 DE STEFANI ZIANO
TE033030 3 3 TE033030 42006172 DE STEFANI ZIANO
-- Mark's a perfect example of the missing/frustrating data I'm dealing with... but we still matched correctly
BG102188 3 1 BG102188 BG1T0543 41008250 BULINS MARK
BG102188 3 2 BG1T0543 TE908583 41008250 BULINS R.J.M.A.
BG102188 3 3 TE908583 41008250 BULINS RICHARD JOHANNES MARTINUS ALPHISIUS
-- Not wanted
BG1T0543 3 2 BG1T0543 TE908583 41008250 BULINS R.J.M.A.
BG1T0543 3 3 TE908583 41008250 BULINS RICHARD JOHANNES MARTINUS ALPHISIUS
TE908583 3 3 TE908583 41008250 BULINS RICHARD JOHANNES MARTINUS ALPHISIUS
-- One more for good measure
BG1T0146 3 1 BG1T0146 BG105905 BG105905 LUIJENT VALERIE
BG1T0146 3 2 BG105905 TE034165 42006121 LUIJENT VALERIE
BG1T0146 3 3 TE034165 42006121 LUIJENT VALERIE
BG105905 3 2 BG105905 TE034165 42006121 LUIJENT VALERIE
BG105905 3 3 TE034165 42006121 LUIJENT VALERIE
TE034165 3 3 TE034165 42006121 LUIJENT VALERIE
Nie wiem, czy wszystko, co czyni go bardziej zrozumiałym informacji lub uczyni Twoje oczy cofnąć do swojej głowa:)
Dzięki za obejrzenie tego!
nie jest dla mnie jasne, dlaczego FG096489 i A5093665 powinny zostać wykluczone z listy root - czy to dlatego, że są one root_users z new_user_id ma wartość null, czy co? Można podać pełniejszy przykład danych wyjściowych z kwerendy, abyśmy mogli zobaczyć kilka dodatkowych kombinacji - z tylko 2 identyfikatorami użytkowników wszystko pojawia się we wszystkich kolumnach, trudno jest zobaczyć wzór. –
Jedynym powodem wykluczenia ich z listy jest to, że chcę, aby były wykluczone:) Jestem otwarty na inne projekty, ale to, co próbuję zrobić z wynikami, wymaga tylko jednej grupy przypadającej na jeden powiązany zbiór użytkowników. Postaram się wyjaśnić więcej w pytaniu, dzięki! –
Czy jesteś w stanie prowadzić zapytanie według daty? Innymi słowy "STARTING WITH FirstEmployment" –