连接Oracle中多行的多个列

时间:2015-10-05 09:12:42

标签: sql oracle

我在stackoverflow中搜索了这个,找到了Concatenate multiple columnsConcatenate multiple rows。但我需要的是两者结合起来 我有一张名为komponen的表:

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方法。但我不知道如何做到这一点并取得理想的结果。请帮忙。

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

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

    select a.y, b.m, 
         (
          SELECT count(*) as cum_count
          FROM users
          WHERE (YEAR(date_register) = a.y and MONTH(date_register) <= b.m) or year(date_register) < a.y
         ) as cum_count 
    from
    (
    SELECT 2015 AS Y UNION ALL SELECT 2014 AS Y
    ) a
    CROSS JOIN 
    (
    SELECT 1 AS m UNION ALL SELECT 2 AS m UNION ALL SELECT 3 AS m UNION ALL SELECT 4 AS m UNION ALL SELECT 5 AS m UNION ALL SELECT 6 AS m UNION ALL SELECT 7 AS m UNION ALL SELECT 8 AS m UNION ALL SELECT 9 AS m UNION ALL SELECT 10 AS m UNION ALL SELECT 11 AS m UNION ALL SELECT 12 AS m
    ) b
    order by a.y, b.m

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; with的组合是删除最后一个运算符。

答案 2 :(得分: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. 连接
  3. 与多行LISTAGG
  4. 连接
  5. 删除最后一个字符SUBSTR(concat_result,1,LENGTH(concat_result)-1)

答案 3 :(得分: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