是否可以构造SQL来连接多行的列值?
以下是一个例子:
表A
PID A B C
表B
PID SEQ Desc A 1 Have A 2 a nice A 3 day. B 1 Nice Work. C 1 Yes C 2 we can C 3 do C 4 this work!
SQL的输出应该是 -
PID Desc A day.||a nice||Have B Nice Work. C this work!||do||we can||Yes
因此,输出表的Desc列基本上是表B中SEQ值的串联,并且值按SEQ的降序附加,并由||分隔。 ?
有关SQL的任何帮助吗?
仅供参考 - 在不使用功能或存储过程的情况下寻找解决方案
答案 0 :(得分:2)
来自here
但我会随时使用某个功能。
SQL> select deptno
2 , rtrim(ename,',') enames
3 from ( select deptno
4 , ename
5 , rn
6 from emp
7 model
8 partition by (deptno)
9 dimension by (row_number() over
10 (partition by deptno order by ename) rn
11 )
12 measures (cast(ename as varchar2(40)) ename)
13 rules
14 ( ename[any] order by rn desc = ename[cv()]||','||ename[cv()+1]
15 )
16 )
17 where rn = 1
18 order by deptno
19 /
DEPTNO ENAMES
---------- ----------------------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
答案 1 :(得分:1)
分层查询应该有效。需要一点额外的技巧,因为你想从每个PID的最高SEQ开始。
SELECT pid, fulldesc FROM (
SELECT pid, SYS_CONNECT_BY_PATH( desc, '||' ) fulldesc, seq, minseq FROM (
SELECT pid, seq, desc,
MAX(seq) OVER (PARTITION BY pid) maxseq,
MIN(seq) OVER (PARTITION BY pid) minseq
FROM tableB
)
START WITH seq = maxseq
CONNECT BY pid = PRIOR pid AND seq = PRIOR seq - 1
)
WHERE seq = minseq
ORDER BY pid
;
修改:在评论中添加过滤器的一种方法:
SELECT pid, fulldesc FROM (
SELECT pid, SYS_CONNECT_BY_PATH( desc, '||' ) fulldesc, seq, minseq FROM (
SELECT pid, seq, desc,
MAX(seq) OVER (PARTITION BY pid) maxseq,
MIN(seq) OVER (PARTITION BY pid) minseq
FROM tableB
WHERE pid IN (SELECT pid FROM tableB WHERE desc='day.')
)
START WITH seq = maxseq
CONNECT BY pid = PRIOR pid AND seq = PRIOR seq - 1
)
WHERE seq = minseq
ORDER BY pid
答案 2 :(得分:1)
以下是很多关于如何做到的例子(其中一些已经提到),包括类似于listagg()的完整实现:
答案 3 :(得分:0)
你想在Oracle中做一些GROUP_CONCAT
在MySQL中做什么吗?
如果存在,您可以使用WM_CONCAT
:
http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php#wm_concat
但它没有证件,所以如果我是你,我就不会在生产中使用它。
不幸的是,在10g上还没有LISTAGG
。
对于10g的生产环境,我会选择Dave Costa的答案。