将一行更新为基于另一行的转换(Oracle)

时间:2019-07-04 10:53:38

标签: sql oracle csv split sql-update

我有一个表,其中有几行(〜100)行。列之一基本上是逗号分隔的字符串列表,这些字符串可能包含也可能不包含空格。现在,我需要另一列作为此列的转换形式:删除空格,用逗号分隔,按字母顺序排序,然后再次用逗号连接。

我有以下适用于一行的SQL(所有其他行都具有相同的值),但是我不知道如何使它在整个表上都能工作。我可能错过了一个地方,但似乎无法正确解决:

update client set sorted = (select listagg(somedata, ',') 
    within group (order by somedata) somedata from (
    with q as (select ','||regexp_replace(unsorted, '\s+', '') as somedata 
    from client)
select regexp_substr(somedata, ',([^,]+)',1,rownum,'i',1) somedata
from q,
(select 1 from q connect by level <= length(regexp_replace(somedata, '[^,]', '')))
));

我想念什么? 谢谢。

1 个答案:

答案 0 :(得分:2)

使用相关子查询:

Oracle设置

CREATE TABLE client ( unsorted, sorted ) AS
  SELECT 'b , c  ,e f, d, a', CAST( NULL AS VARCHAR2(30) ) FROM DUAL UNION ALL
  SELECT 'z , y, x,w,v ,u', CAST( NULL AS VARCHAR2(30) ) FROM DUAL;

更新

UPDATE client c
SET sorted = (
  SELECT LISTAGG(
           REGEXP_REPLACE( REGEXP_SUBSTR( c.unsorted, '[^,]+', 1, LEVEL ), '\s+' ),
           ','
         ) WITHIN GROUP (
           ORDER BY REGEXP_REPLACE( REGEXP_SUBSTR( c.unsorted, '[^,]+', 1, LEVEL ), '\s+' )
         )
  FROM   DUAL
  CONNECT BY LEVEL <= REGEXP_COUNT( c.unsorted, ',' ) + 1
)

输出

SELECT * FROM client;
UNSORTED          | SORTED     
:---------------- | :----------
b , c  ,e f, d, a | a,b,c,d,ef 
z , y, x,w,v ,u   | u,v,w,x,y,z

db <>提琴here

相关问题