2015-10-05 36 views
0

我在stackoverflow中搜索到了并找到了Concatenate multiple columnsConcatenate multiple rows。但我需要的是将两者结合起来。
我有表名为komponen:在Oracle中连接来自多行的多个列

id urut tipe c_string c_number op 
--------------------------------------------- 
A1 1  S  GP   NULL  * 
A1 2  N  NULL  5   /
A1 3  N  NULL  100   + //Ignore the last op for each groups. 
A2 1  S  GP   NULL  - 
A2 2  N  NULL  1000  ///Ignore the last op for each groups. 

期望的结果:

id  concat_result 
------------------------ 
A1  GP * 5/100 
A2  GP - 1000 

这可能是使用LISTAGGGROUP BY方法。但我没有任何线索如何做到这一点,并达到预期的效果。请帮忙。

回答

1

这与here的一些修改。新增||(串连)在LISTAGG

SELECT ID, 
    LISTAGG (
     CASE 
     WHEN TIPE = 'v' THEN 
     C_STRING 
     ELSE 
     TO_CHAR (C_NUMBER) 
     END || OP, 
     ' ' 
    ) WITHIN GROUP (ORDER BY URUT) AS CONCAT_RESULT 
FROM KOMPONEN 
GROUP BY ID; 
+0

这给我'GP * 5/100 +'而不是' GP * 5/100'。我想忽略每个组的最后一个操作。 –

+0

我加了substr删除最后一个操作。谢谢。 –

1

你的预感是正确的。在这个解决方案中,我假设c_string和c_number是相互排斥的,即一个将不为空。

with t as (
    select id, listagg(nvl(c_string, c_number)||' '||op, ' ') within group (order by urut) result 
    from komponen 
    group by id 
) 
select id, substr(result, 1, length(result)-2) 
from t; 

withsubstr()的结合是除去最后的算。

1

您可以使用:

SqlFiddleDemo

WITH cte AS 
(
    SELECT 
     id, 
     LISTAGG(string , '') WITHIN GROUP (ORDER BY urut) AS concat_result 
    FROM(SELECT id, urut, 
     NVL(c_string, '') || ' ' || NVL(c_number, '') || ' ' || NVL(op, '') AS string 
     FROM komponen) 
    GROUP BY id 
) 
SELECT 
    id, 
    SUBSTR(concat_result,1,LENGTH(concat_result)-1) AS concat_result 
FROM cte 

工作原理:

  1. 连接具有排NVL(c_string, '') || ' ' || NVL(c_number, '') || ' ' || NVL(op, '')
  2. 连接具有多行LISTAGG
  3. 删除最后一个字符SUBSTR(concat_result,1,LENGTH(concat_result)-1)
1

一种方式是通过使用row_number分析功能和listaggr

SQL> WITH table_("ID", urut, tipe, c_string, c_number, op) AS 
    2 (SELECT 'A1', 1, 'S', 'GP', NULL, '*' from dual union all 
    3 SELECT 'A1', 2, 'N', NULL, '5', '/' from dual union all 
    4 SELECT 'A1', 3, 'N', NULL, '100', '+' from dual union all 
    5 SELECT 'A2', 1, 'S', 'GP', NULL, '-' from dual union all 
    6 SELECT 'A2', 2, 'N', NULL, '1000', '/' from dual), 
    7 ------- 
    8 -- End if Data preparation 
    9 ------- 
10 table2_ AS (SELECT t.*, row_number() OVER (partition BY "ID" ORDER BY URUT DESC) AS rn 
11 FROM table_ t) 
12 SELECT "ID", 
13   listagg(coalesce(c_string, c_number) || ' ' || CASE 
14      WHEN rn = 1 THEN 
15      NULL 
16      ELSE 
17      op 
18     END, 
19     ' ') within GROUP(ORDER BY urut) AS EXPR 
20 FROM table2_ 
21 GROUP BY "ID" 
22/

输出

ID EXPR 
-- -------------------------------------------------------------------------------- 
A1 GP * 5/100 
A2 GP - 1000