[英]Write the array function from Postgres in Oracle Syntax
在Postgres中,我会这样做:
SELECT main.*
, array(SELECT columnA FROM tableB alt WHERE alt.columnB = main.columnB) AS columnAs_to_tableA
FROM tableA main
在Oracle 10中如何做同样的事情? 应当指出,我不能使用listagg。 我找到了一个类似问题的答案: Oracle 10g中的聚合字符串连接我完全不知道此答案的工作方式,也不知道这是否真的是“正确的”解决方案,因为它从未被标记为已回答/接受。
我想用一个示例来回答这个问题,该示例使用我提供的一对一比较的相同表名,对于寻求相同答案的其他人来说可能是最好的。
谢谢
编辑1:我应该补充一点,我想避免引入新的架构元素,例如表,函数等。
编辑2:删除数组的要求。 以逗号分隔的字符串就足够了。
如果要返回集合,则需要创建一个类型,然后使用collect
来填充该类型。
CREATE TYPE typ_columnA_nt
AS TABLE OF <<columnA data type>>
然后可以使用collect
功能
SELECT main.*
, cast( collect(SELECT columnA
FROM tableB alt
WHERE alt.columnB = main.columnB)
as typ_columnA_nt ) AS columnAs_to_tableA
FROM tableA main
如果要返回光标,可以使用cursor
功能
SELECT main.*,
cursor( SELECT columnA
FROM tableB alt
WHERE alt.columnB = main.columnB ) as columnAs_to_tableA
FROM tableA main
如果要返回用逗号分隔的字符串,Tim Hall 在Oracle中提供了规范的字符串聚合技术列表。 在无法使用listagg
版本中,我更喜欢创建一个用户定义的聚合函数 ,该函数可让您
select main.*,
(select string_agg(columnA)
from tableB alt
where alt.columnB = main.columnB) as columnAs_to_tableA
from tableA main
如果您限于不涉及创建新对象的解决方案,则最简单的选择是使用wm_concat
尽管这不受官方支持
select main.*,
(select wm_concat(columnA)
from tableB alt
where alt.columnB = main.columnB) as columnAs_to_tableA
from tableA main
如果您无法创建任何支持对象,并且无法使用不受支持的功能,那么您将sys_connect_by_path
于旧的row_number
和sys_connect_by_path
选项 ,该选项有些丑陋。 我认为您想要这样的东西,但是我犯了一个很小的语法错误的可能性很大。
select main.*,
agg.value_string
from tableA main
left join (select alt_outer.columnB,
ltrim(max(sys_connect_by_path(alt_outer.columnA,','))
keep( dense_rank last order by alt_outer.columnA ),
',') as value_string
from (select alt.columnA,
alt.columnB,
row_number() over (partition by alt.columnB
order by alt.columA) as curr,
row_number() over (partition by alt.columnB
order by alt.columA) -1 as prev
from tableB alt) alt_outer
group by alt_outer.columnB
connect by alt_outer.prev = prior alt_outer.curr
and alt_outer.columnB = prior alt_outer.columnB
start with alt_outer.curr = 1) agg
on( main.columnB = agg.columnB )
另一个选择是使用XML函数
SELECT main.* ,
tableB_alt.list AS columnAs_to_tableA
FROM tableA main
LEFT JOIN ( SELECT columnB ,
TRIM(TRAILING ','
FROM
XMLAGG(
XMLELEMENT(E,columnA||',')
).EXTRACT('//text()')
) list
FROM tableB
GROUP BY columnB ) tableB_alt
ON tableB_alt.columnB = main.columnB
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.