如何将两列的id连接到一个字段中,并用它们的名称替换这些ID

时间:2013-05-06 16:41:17

标签: sql oracle

这些是我的表格。

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上工作。你能帮忙吗?

3 个答案:

答案 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

SQL Fiddle Demo

基本上它使用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