Haben Sie eine schwere Abfrage (dauert 15 Minuten zum Ausführen), aber es gibt mehr Ergebnisse als ich brauche. Es ist eine CONNECT BY-Abfrage, und ich bekomme Knoten, die in den Ergebnissen des Stammknotens untergeordnet sind. D.h .:Ausschließen von Ergebnissen, die in einer anderen Spalte einer CONNECT BY-Abfrage angezeigt werden
Ted
Bob
John
Bob
John
John
Normalerweise wird die Art und Weise, dies zu lösen ist mit einem START MIT Bedingung, in der Regel die Eltern eines Knotens erfordert null zu sein. Aber aufgrund der Art der Abfrage habe ich nicht die START WITH-Werte, mit denen ich vergleichen muss, bis ich die vollständige Ergebnismenge habe. Ich versuche im Grunde, meine Ergebnisse doppelt abzufragen, um QUERY STUFF START WITH RECORDS zu sagen, die NICHT IN DIESEM MATERIAL SIND.
Hier ist die Abfrage (mit Hilfe von Nicholas Krasnov gebaut, hier: 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;
Das bin ich zu verwandten Benutzer gibt Ergebnisse (basierend weg von User_id umbenennt oder SAP-IDs zugeordnet) das sieht so aus:
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
Was ich brauche ist ein Weg zu Filtern Sie die erste join (select connect_by_root(user_id)...
, um FG096489
und A5093665
von der Root-Liste auszuschließen.
Die beste START WITH
ich denken kann wie folgt aussehen würde (noch nicht getestet):
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)
... aber ich meine 15 Minuten Abfrage zweimal effektiv ausgeführt wird.
Ich habe mit Partitionen in der Abfrage untersucht, aber es gibt nicht wirklich eine Partition ... Ich möchte auf die volle Ergebnismenge von new_user_ids schauen. Habe auch analytische Funktionen wie rank() erforscht ... meine Trickkiste ist leer.
Irgendwelche Ideen?
Klärung
Der Grund, warum ich nicht die zusätzlichen Datensätze in der Wurzelliste will, weil ich für jeden Benutzer nur eine Gruppe von Ergebnissen will. Wenn Bob Smith während seiner Karriere vier Konten hatte (Leute kommen und gehen häufig, als Angestellte und/oder Auftragnehmer), möchte ich mit einer Reihe von Konten arbeiten, die Bob Smith gehören.
Wenn Bob als Auftragnehmer kam, in einen Mitarbeiter umgewandelt, ging, kam als Auftragnehmer in einem anderen Land zurück und ging zu einer rechtlichen Organisation zurück, die jetzt in unserem SAP-System seinen Account umbenennen/ketten könnte wie folgt aussehen:
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)
im obigen Beispiel werden die vier Konten entweder durch ein new_user_id
Feld verknüpft, die festgelegt wurde, wenn der Benutzer umbenannt wurde oder durch die gleiche SAP-ID mit.
Da HR den Geschäftsprozess häufig nicht befolgt, kann die Rückgabe von Benutzern zu einer Wiederherstellung dieser vier IDs führen. Ich muss alle IDs für Bob Smith analysieren und sagen "Bob Smith kann TE110001 nur wiederherstellen", und einen Fehler zurückwerfen, wenn sie versuchen, etwas anderes wiederherzustellen. Ich muss es für mehr als 90.000 Datensätze tun.
Die erste Spalte "Bob Smith" ist nur eine Kennung für die Gruppe der zugeordneten Konten. In meinem ursprünglichen Beispiel verwende ich die root-Benutzer-ID als Kennung (z. B. US0T0001). Wenn ich mit Vor-/Nachnamen Benutzer identifiziere, stoße ich auf Kollisionen.
So Bob Smith würde wie folgt aussehen:
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)
... wo 1, 2, 3, 4 die Pegel in der Hierarchie sind.
Da US0T0001, US001101, EB0T0001 und TE110001 alle berücksichtigt werden, möchte ich keine andere Gruppe für sie. Aber die Ergebnisse habe ich habe jetzt diese Konten in mehreren Gruppen aufgeführt:
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
Dies verursacht zwei Probleme:
- Wenn ich die Ergebnisse für eine Benutzer-ID abfragen, erhalte ich Treffer von mehreren Gruppen
- Jede Gruppe meldet eine andere erwartete Benutzer-ID für Bob Smith.
Sie bat um einen erweiterten Satz von Aufzeichnungen ... hier sind einige aktuelle Daten:
-- 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
Nicht sicher, ob alles, was info macht deutlicher, oder wird Ihre Augen machen rollen wieder in Ihre Kopf:)
Danke für das Betrachten!
ist mir nicht sehr klar, warum FG096489 und A5093665 aus der Root-Liste ausgeschlossen werden sollten - ist es, weil sie root_users mit new_user_id ist null, oder was könnten Sie ein vollständigeres Beispiel für die Ausgabe von der Abfrage geben, so dass wir sehen können ein paar mehr Kombinationen - mit nur 2 Benutzer-IDs erscheinen alle in allen Spalten, es ist schwer, das Muster zu sehen. –
Der einzige Grund, sie von der Liste auszuschließen, ist, dass ich sie ausgeschlossen habe:) Ich bin offen für andere Designs, aber was ich mit den Ergebnissen versuche, erfordert, dass es nur eine Gruppe pro assoziierten Benutzergruppe gibt. Will versuchen, mehr in der Frage zu erklären, danke! –
Können Sie die Abfrage nach Datum steuern? Mit anderen Worten: 'STARTING WITH FirstEmployment' –