0

我有一个表格,其中包含如下数据

Column A      Column B
-------------------------
1             POW
2             POW
1             POWPRO
1             PRO
2             PRO
1             PROUTL
1             TNEUTL
1             UTL
1             UTLTNE

我需要如下输出

输出

Column A      Column B

1,2           POW,POWPRO,PRO,PROUTL,TNEUTL,UTL,UTLTNE  

我尝试了以下查询。但是输出不一样。

select dbms_lob.substr( ltrim(REGEXP_REPLACE(REPLACE(
     REPLACE(
       XMLAGG(
         XMLELEMENT("A",COLUMN_A )
           ORDER BY COLUMN_A).getClobVal(),
         '<A>',','),
         '</A>',' '),'([^,]+)(,\1)+', '\1'),
dbms_lob.substr( ltrim(REGEXP_REPLACE(REPLACE(
     REPLACE(
       XMLAGG(
         XMLELEMENT("A",COLUMN_B )
           ORDER BY COLUMN_B).getClobVal(),
         '<A>',','),
         '</A>',' '),'([^,]+)(,\1)+', '\1') from table_name

但输出是

Column A     Column B
-------------------------------------------------
1,2          POW ,POWPRO ,PROUTL ,TNEUTL ,UTLTNE 

我只想使用 regexp_replace 来搜索模式。请帮帮我。

4

2 回答 2

0

您可以使用 Oracles 集合。CAST()配对COLLECT()可以将值聚合到用户定义的集合中,然后SET()消除重复项。然后您可以使用LISTAGG()将集合转换为字符串。

甲骨文设置

CREATE TYPE intlist IS TABLE OF INT;
/

CREATE TYPE stringlist IS TABLE OF VARCHAR2(4000);
/

CREATE TABLE table_name ( ColA NUMBER(5,0), ColB VARCHAR2(20) );
INSERT INTO table_name
  SELECT 1, 'POW' FROM DUAL UNION ALL
  SELECT 2, 'POW' FROM DUAL UNION ALL
  SELECT 1, 'POWPRO' FROM DUAL UNION ALL
  SELECT 1, 'PRO' FROM DUAL UNION ALL
  SELECT 2, 'PRO' FROM DUAL UNION ALL
  SELECT 1, 'PROUTL' FROM DUAL UNION ALL
  SELECT 1, 'TNEUTL' FROM DUAL UNION ALL
  SELECT 1, 'UTL' FROM DUAL UNION ALL
  SELECT 1, 'UTLTNE' FROM DUAL;

查询

SELECT ( SELECT LISTAGG( COLUMN_VALUE, ',' )
                  WITHIN GROUP ( ORDER BY COLUMN_VALUE )
         FROM   TABLE( ColA ) ) AS ColA,
       ( SELECT LISTAGG( COLUMN_VALUE, ',' )
                  WITHIN GROUP ( ORDER BY COLUMN_VALUE )
         FROM   TABLE( ColB ) ) AS ColB  
FROM   (
  SELECT SET( CAST( COLLECT( ColA ORDER BY ColA ) AS INTLIST ) ) ColA,
         SET( CAST( COLLECT( ColB ORDER BY ColB ) AS STRINGLIST ) ) ColB
  FROM   table_name
);

输出

ColA ColB
---- ---------------------------------------
1,2  POW,POWPRO,PRO,PROUTL,TNEUTL,UTL,UTLTNE
于 2016-06-23T00:01:34.207 回答
0

我将首先假设您的实际列名是Aand B,而不是"Column A"and "Column B"。如果该假设是错误的,您需要做的就是更改下面的名称。

您想要LIST_AGG(适用于 Oracle 11g 及更高版本):

SELECT
    LISTAGG(A, ',') WITHIN GROUP (ORDER BY A) AS A_VALUES
FROM TABLE_NAME;

不要被一WITHIN GROUP点点扔掉。这是一个“分析函数”,它只是 Oracle 对其他数据库所称的窗口函数的名称。分析/窗口函数的基本思想是,它允许您访问相邻结果行中的数据以确定当前行的值。他们擅长的一个简单例子是累积和。

在这种情况下,它是分析/窗口的事实是多余的。我们只是用它来聚合。但是,我们必须提供该WITHIN GROUP部分以防止语法错误。我们告诉它按什么排序列表,在这种情况下,它只是我们正在聚合的列。您可以使用分析/窗口函数做更多事情,但这不是讨论这些功能的地方。

DISTINCT由于您需要这些值,因此事情会变得有些复杂:

SELECT
    LISTAGG(A, ',') WITHIN GROUP (ORDER BY A) AS A_VALUES
FROM (
    SELECT DISTINCT A
    FROM TABLE_NAME
);

甚至更复杂,因为你想要两列:

SELECT *
FROM (
    SELECT
        LISTAGG(A, ',') WITHIN GROUP (ORDER BY A) AS A_VALUES
    FROM (
        SELECT DISTINCT A
        FROM TABLE_NAME
    )
) A_VALS,
(
    SELECT
        LISTAGG(B, ',') WITHIN GROUP (ORDER BY B) AS B_VALUES
    FROM (
        SELECT DISTINCT B
        FROM TABLE_NAME
    )
) B_VALS

最后一个给你你想要的。它只是根据子查询中每一列的不同值创建一个字符串,然后执行完全连接(逗号,因为没有过滤器)将两列放在一起。每个子查询返回一行,因此您在最终结果中只会得到一行。

于 2016-06-22T21:29:38.277 回答