oracle获取行的值给产量,递归oracle sql识别值

本文探讨了如何使用Oracle的CONNECT BY和LISTAGG函数来解决递归查询问题,特别是在处理具有层级关系的数据时。示例中展示了如何从具有类别和数据集市类型的记录中提取源信息,通过递归解析直到找到类别类型,然后使用LISTAGG聚合源信息。这种方法对于处理具有层次结构的数据表非常有用。
摘要由CSDN通过智能技术生成

我有一个表TABA(PK:NAME)这样存储NAME,NAME_TYPE,SOURCE:

NAME  NAME_TYPE SOURCE

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

Name1 Category  S1

Name2 Category  S2

Name3 Datamart

Name4 Category  S1

Name5 Datamart

Name6 Datamart

Name7 Category  S3

上面的注释:仅当NAME_TYPE = Category时,数据中才存在源。

我还有另一个表TABA_PARENT,它以这种方式基于name_type存储NAME,PARENT_NAME和NAME列之间的关系。

Datamart与Category的关系是一对多的。

NAME   PARENT_NAME

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

Name3  Name1

Name3  Name2

Name3  Name4

Name3  Name5

Name5  Name1

Name5  Name6

Name6  Name7

我的要求是获取NAME_TYPE = Datamart的TABA的源(当前,TABA中不存在)

预期产量:

SOURCE COLUMN FOR Name3

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

S1,S2,S3

诀窍是递归推导Name3的SOURCE,直到它映射到TABA_PARENT中的Category。

在上面的示例中:

Name3映射到PARENT_NAME Name1,Name2,Name4,Name5。

其中3个(name1,Name2,Name4)属于name_type = Category,因此在TABA中提供了不同的来源-S1,S2

第四个PARENT_NAME Name5是一个name_type Datamart(源信息不可用),需要进一步扩展,直到达到name_type = Category。

我们知道Name5映射到PARENT_NAME Name1,Name6。

Name1是一个类别,因此可以推论出来源。

Name6再次是Datamart。

但是,Name6最终被映射到属于Category的Name7,因此源可用-S3

如上所示,必须递归解析所有映射,直到它们到达name_type Category以标识不同的源。

Expected RESULT: S1,S2,S3

我正在尝试是否可以使用listagg或类似的东西来完成此操作(小的pl / sql代码也可以,但是如果可能的话,请选择单选)

我很难递归地执行此操作。

任何帮助将非常感激。

我无法回答自己的问题。 因此,我在评论部分中回答。

感谢任何尝试此操作的人。 我尝试使用" connect by"和listagg的组合,并达到了预期的效果。 在组(按源排序)中选择listagg(source ,,),按final_source从(选择不同的b.source源-,从taba_parent a,taba b中选择,其中b.name = a.parent_name和b.name_type = Category按先前a连接 .parent_name = a.name以a.name = Name3开头);

如果您不愿意接受其他第一章的答案之一,则将其发布为答案。

我试图这样做,但是该网站不允许我接受48小时的自己的答案。 之后,我将接受自己的回答。

如注释中所述,可以使用listagg()的组合来完成此操作,该组合可从Oracle 11.2及更高版本和connect by获得。如果您不使用11.2,则还有许多其他字符串聚合技术可用。

SELECT listagg(SOURCE, ',' ) WITHIN GROUP ( ORDER BY SOURCE )

FROM ( SELECT DISTINCT SOURCE

FROM taba a

JOIN ( SELECT parent_name

FROM taba_parent

START WITH name = 'Name3'

CONNECT BY prior parent_name = name

) b

ON a.name = b.parent_name

)

仅存在distinct子查询,因为您有多个相同的源。这将返回S1,S2,S3。

为了获得不同名称的相同名称,可以更改START WITH子句。例如将其更改为start with name = 'Name5'将返回S1,S3。

数据集市没有源这一事实无关紧要,因为您仅在taba_parent表上使用分层查询,仅在拥有所需信息时才加入taba表。

这里有一个SQL Fiddle演示。

谢谢大家,我看到提供的解决方案与我提出的解决方案相同,并且所有这些工作都可以解决。

感谢任何尝试此操作的人。

我尝试使用" connect by"和listagg的组合,并达到了预期的效果。

SELECT listagg(SOURCE,',') WITHIN GROUP (ORDER BY SOURCE) final_source FROM (

SELECT

DISTINCT

b.source SOURCE--,

FROM taba_parent a, taba b

WHERE b.name = a.parent_name

AND b.name_type = 'Category'

CONNECT BY prior a.parent_name = a.name

START WITH a.name = 'Name3'

);

您需要一个层次查询(connect by)来获得"最终父母",然后您需要使用listagg将各项串联在一起。我只有Oracle 10g,所以没有listagg。这是层次结构位:

SELECT DISTINCT SOURCE FROM

(

SELECT taba_parent.name, taba_parent.parent_name, taba.source

FROM

taba_parent

INNER JOIN taba ON taba_parent.parent_name = taba.name

)

WHERE name IN (SELECT name FROM taba WHERE name_type = 'Datamart')

CONNECT BY name = parent_name

START WITH SOURCE IS NOT NULL

这给出:

SOURCE

S3

S2

S1

您可以使用listagg获取S3,S2,S1

谢谢大家,我看到提供的解决方案与我在您的回复和所有这些工作之前提出的解决方案相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值