如何通过两列之间的差异创建新列?

问题描述 投票:0回答:2

我使用join,listagg等创建新表。我使用listagg函数确定了两列。该列包括以下信息。

Listagg_1_Column | Listagg_2_Column
---------------- |-----------------
123,234,565,321  |  123,234

我想在此表中添加新列。 Listagg_1_Column和Listagg_2_Column之间包含新列,如下所示]

New_Column
----------
565,321

为此,我使用了replace(Listagg_1_Column,Listagg_2_Column,'')语句,但是我得到了错误的结果。如何通过更改查询获取新列?任何帮助将不胜感激。预先感谢。

sql oracle plsql replace oracle12c
2个回答
1
投票

我有测试数据:

CREATE TABLE data ( col1, col2 ) AS
SELECT '123,234,565,321', '123,234' FROM DUAL UNION ALL
SELECT '123,234,1123,2345', '123,234' FROM DUAL UNION ALL
SELECT '123,565,321,234', '123,234' FROM DUAL

然后,您可以使用XMLTABLE分割字符串,然后使用MINUS查找两个集合之间的差异,然后将结果整理为一个集合,然后可以集合集合:

SELECT col1,
       col2,
       ( SELECT LISTAGG( column_value, ',' ) WITHIN GROUP ( ORDER BY column_value )
         FROM   TABLE( d.new_col )
       ) AS new_col
FROM   (
  SELECT col1,
         col2,
         CAST(
           MULTISET(
             ( SELECT TO_NUMBER( column_value )
               FROM   XMLTABLE( ('"' || REPLACE( d.col1, ',', '","' ) || '"') )
               MINUS
               SELECT TO_NUMBER( column_value )
               FROM   XMLTABLE( ('"' || REPLACE( d.col2, ',', '","' ) || '"') )
             )
           ) AS SYS.ODCINUMBERLIST
         ) AS new_col
  FROM   data d
) d;

哪个输出:

COL1 | COL2 | NEW_COL:---------------- | :------ | :--------123,234,565,321 | 123,234 | 321,565123,234,1123,2345 | 123,234 | 1123,2345123,565,321,234 | 123,234 | 321,565

db <>小提琴here


0
投票

在这里,我将两列转换为两个表。之后,很容易找到差异。

with xxx
     as (select '123,565,321,234' listagg_1_column,
                '123,234' listagg_2_column
           from DUAL)
  select listagg_1_column,
         listagg_2_column,
         LISTAGG (myrow, ',') within group (order by myrow) diff
    from (    select REGEXP_SUBSTR (listagg_1_column,
                                    '[^,]+',
                                    1,
                                    LEVEL)
                        myrow,
                     listagg_1_column,
                     listagg_2_column
                from xxx
          connect by REGEXP_SUBSTR (listagg_1_column,
                                    '[^,]+',
                                    1,
                                    LEVEL)
                        is not null) xx
   where xx.myrow not in (    select REGEXP_SUBSTR (listagg_2_column,
                                                    '[^,]+',
                                                    1,
                                                    LEVEL)
                                        myrow
                                from xxx
                          connect by REGEXP_SUBSTR (listagg_2_column,
                                                    '[^,]+',
                                                    1,
                                                    LEVEL)
                                        is not null)
group by listagg_1_column, listagg_2_column

上面的代码仅适用于一个计数。这里适用于多记录。

WITH data ( listagg_1_column, listagg_2_column ) 
     AS (SELECT '123,234,565,321', 
                '123,234' 
         FROM   dual 
         UNION ALL 
         SELECT '123,234,1123,2345', 
                '123,234' 
         FROM   dual 
         UNION ALL 
         SELECT '123,565,321,234', 
                '123,234' 
         FROM   dual 
         UNION ALL 
         SELECT '123,565,321,234', 
                '321,565' 
         FROM   dual) 
SELECT listagg_1_column, 
       listagg_2_column, 
       Listagg (myrow, ',') 
         within GROUP (ORDER BY myrow ) diff 
FROM   (SELECT DISTINCT Regexp_substr (xx.listagg_1_column, '+[^,]+', 1, LEVEL) 
                        myrow, 
                        xx.listagg_1_column, 
                        xx.listagg_2_column, 
                        Regexp_count (listagg_1_column, '[^,]+') 
                        a, 
                        LEVEL 
        FROM   data xx 
        CONNECT BY Regexp_count (listagg_1_column, '[^,]+') >= LEVEL 
        ORDER  BY listagg_1_column, 
                  LEVEL)xx 
WHERE  xx.myrow NOT IN (SELECT Regexp_substr (yy.listagg_2_column, '[^,]+', 1, 
                               LEVEL) 
                               myrow 
                        FROM   data yy 
                        WHERE  XX.listagg_1_column = YY.listagg_1_column 
                               AND XX.listagg_2_column = YY.listagg_2_column 
                        CONNECT BY Regexp_count (yy.listagg_2_column, '[^,]+') 
                                   >= LEVEL 
                              ) 
GROUP  BY listagg_1_column, 
          listagg_2_column 

db <>提琴here

© www.soinside.com 2019 - 2024. All rights reserved.