这些是我的表格。
Step
stepid name
a place1
b place2
c place3
d place4
e place5
f place6
Stage
stageid start finish
1 a b
2 b c
3 c d
4 d e
5 e f
Trip
tripid stageid
1 1
1 2
1 3
1 4
1 5
我想实现此查询结果
tripid stageid
1 place1,place2,place3,place4,place5,place6
我知道如何将所有ID放入一个字段以及如何用指定的名称替换id。但是我不知道如何加入这两种解决方案。
这是我用于将id放入一个字段的sql。
SELECT REPLACE(stageid,'''') as stages
FROM (SELECT SYS_CONNECT_BY_PATH(stageid,' ') stageid, level
FROM trip
START WITH stageid = (select min(stageid) from trip)
CONNECT BY PRIOR stageid < stageid
ORDER BY level DESC)
WHERE rownum = 1;
开始和结束是stepid的外键,trip table的stageid是Stage表中stageid的外键 我在oracle developer ver 3.2上工作。你能帮忙吗?
答案 0 :(得分:1)
试试这个,请注意我已将start
重命名为startid
:
SELECT tripid, REPLACE(stageid,'''') as stages
FROM (
SELECT tripid, SYS_CONNECT_BY_PATH(step.name,' ') stageid, level
FROM trip
JOIN stage USING(stageid)
JOIN step ON stage.startid=step.stepid
START WITH stageid = (select min(stageid) from trip)
CONNECT BY PRIOR stageid < stageid
ORDER BY level DESC
)
WHERE rownum = 1;
它只输出起始步骤名称而不是ids,如果你想获得旅行中的所有地方,只需加入开始和结束并使用不同的
就可能更容易如果有人有更好的想法,这是一个小提琴: http://sqlfiddle.com/#!4/1d5d5/8
答案 1 :(得分:1)
假设您有权访问LISTAGG
,那么这是一个非常接近的选项:
SELECT tripid, stages || ',' || step.name
FROM (
SELECT trip.tripid,
LISTAGG(step.name, ',') within group (order by stage.stageid) stages,
MAX(stage.stageId) maxStageId
FROM stage
INNER JOIN step on stage.startstep = step.stepid
INNER JOIN trip on stage.stageid = trip.stageid
GROUP BY trip.tripid
) t INNER JOIN stage ON t.maxStageId = stage.stageId
INNER JOIN step on stage.finishstep = step.stepid
基本上它使用startstep来构建列表,然后根据最大阶段id连接最后的完成步骤。
答案 2 :(得分:1)
我认为最简单的方法就是使用listagg()
来聚合字符串。将表连接在一起然后汇总它们:
select t.tripid,
listagg(st.name, ',') within group (order by st.stepid)
from trip t join
stage s
on t.stageid = s.stageid join
step st
on st.stepid in (s.start, s.finish)
group by t.tripid