在Postgres中,我会这样做:
SELECT main.*
, array(SELECT columnA FROM tableB alt WHERE alt.columnB = main.columnB) AS columnAs_to_tableA
FROM tableA main
Oracle 10中如何做同样的事情?应该注意的是我不能使用listagg。我找到了类似问题的答案:Aggregate String Concatenation in Oracle 10g 我不知道这个答案是如何起作用的,也不知道这是否是“正确的”解决方案,因为它从未被标记为已接听/接受。
我想用一个例子回答这个问题,使用我提供的一对一比较的表名,对于寻求相同答案的其他人来说可能效果最好。
谢谢
编辑1:我应该补充一点,我想避免引入新的架构元素,如表格,函数等......
编辑2:删除阵列的要求。逗号分隔的字符串就足够了。
答案 0 :(得分: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有一个string aggregation techniques in Oracle的规范列表。在listagg
不可选的版本中,我的偏好是创建user-defined aggregate function,这样您就可以
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
如果你不能创建任何支持对象,并且你不能使用不支持的函数,那么你就会陷入旧的row_number
and sys_connect_by_path
option,这有点难看。我想你会想要这样的东西,但我有一个很小的机会,我犯了一个小的语法错误。
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