gpt4 book ai didi

sql - 排除出现在 CONNECT BY 查询的另一列中的结果

转载 作者:行者123 更新时间:2023-12-04 15:46:24 25 4
gpt4 key购买 nike

有一个繁重的查询(运行需要 15 分钟),但它返回的结果比我需要的要多。这是一个 CONNECT BY 查询,我得到的是根节点结果中的后代节点。 IE。:

Ted
Bob
John
Bob
John
John

通常,解决此问题的方法是使用 START WITH 条件,通常要求节点的父节点为空。但是由于查询的性质,在获得完整结果集之前,我没有需要比较的 START WITH 值。我基本上是想对我的结果进行双重查询,以说 QUERY STUFF START WITH RECORDS THAT AREN'T IN THE STUFF。

这是查询(在 Nicholas Krasnov 的帮助下构建,此处: 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;

这为我提供了有关相关用户的结果(基于 user_id 重命名或关联的 SAP ID),如下所示:
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

我需要的是一种过滤第一个 join (select connect_by_root(user_id)... 的方法排除 FG096489A5093665从根列表。

最好的 START WITH我能想到的看起来像这样(尚未测试):
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)

...但我有效地执行了两次 15 分钟的查询。

我已经在查询中查看了使用分区,但实际上并没有分区...我想查看 new_user_ids 的完整结果集。还探索了诸如 rank() 之类的分析函数......我的技巧袋是空的。

有任何想法吗?

澄清

我不想要根列表中的额外记录的原因是因为我只想要每个用户的一组结果。即,如果 Bob Smith 在他的职业生涯中拥有四个帐户(人们经常来来去去,作为员工和/或承包商),我想使用一组都属于 Bob Smith 的帐户。

如果 Bob 作为承包商来到这里,转换为员工,离开,作为承包商返回另一个国家/地区,并离开/返回到现在在我们 SAP 系统中的合法组织,他的帐户重命名/链可能如下所示:
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)

在上面的示例中,四个帐户通过 new_user_id 链接。用户重命名时或通过具有相同 SAP ID 时设置的字段。

由于 HR 经常无法遵循业务流程,因此返回的用户最终可能会恢复这四个 ID 中的任何一个。我必须分析 Bob Smith 的所有 ID 并说“Bob Smith 只能恢复 TE110001”,如果他们尝试恢复其他内容,则返回错误。我必须为 90,000 多条记录做这件事。

第一列“Bob Smith”只是关联帐户组的标识符。在我的原始示例中,我使用根用户 ID 作为标识符(例如 US0T0001)。如果我使用名字/姓氏来识别用户,最终会发生冲突。

所以鲍勃史密斯看起来像这样:
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)

... 其中 1、2、3、4 是层次结构中的级别。

由于US0T0001、US001101、EB0T0001和TE110001都被占了,我不想再给他们一个组。但是我现在的结果将这些帐户列在多个组中:
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

这会导致两个问题:
  • 当我查询用户 ID 的结果时,我得到了来自多个组的点击
  • 每个组将为 Bob Smith 报告不同的预期用户 ID。

  • 您要求扩展记录集……以下是一些实际数据:
    -- 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

    不确定所有这些信息是否会让你更清楚,还是会让你的眼睛回到你的脑海里:)

    谢谢你看这个!

    最佳答案

    我想我有。我们让自己专注于时间顺序,而实际上这并不重要。您的 START WITH 子句应该是“NEW_USER_ID IS NULL”。

    要获得时间顺序,您可以“ORDER BY cudroot.node_level * -1”。

    我还建议您考虑使用 WITH 子句来形成您的基本数据并对其执行分层查询。

    关于sql - 排除出现在 CONNECT BY 查询的另一列中的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12959153/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com