按行对逗号分隔的数据集进行排序

时间:2019-07-03 13:01:35

标签: sql oracle db2 listagg

这就是给出的

Numbers         Powers
4,5,1           WATER,FIRE
6,3,9           ICE,WATER,FIRE

我的要求是(排序)

Numbers               Powers
1,4,5                 FIRE,WATER
3,6,9                 FIRE,ICE,WATER .

我要按顺序排序!如何在数据库中做到这一点?

3 个答案:

答案 0 :(得分:2)

将列拆分为行,然后将它们聚合回去,进行排序。

SQL> with test (id, num, pow) as
  2    (select 1, '4,5,1', 'water,fire'     from dual union all
  3     select 2, '6,3,9', 'ice,water,fire' from dual
  4    ),
  5  temp as
  6    -- split columns to rows
  7    (select id,
  8            regexp_substr(num, '[^,]+', 1, column_value) num1,
  9            regexp_substr(pow, '[^,]+', 1, column_value) pow1
 10     from test join table(cast(multiset(select level from dual
 11                                        connect by level <= regexp_count(num, ',') + 1
 12                                       ) as sys.odcinumberlist)) on 1 = 1
 13    )
 14    -- aggregate them back, sorted
 15  select id,
 16         listagg(num1, ',') within group (order by to_number(num1)) num_result,
 17         listagg(pow1, ',') within group (order by pow1) pow_result
 18  from temp
 19  group by id;

        ID NUM_RESULT                     POW_RESULT
---------- ------------------------------ ------------------------------
         1 1,4,5                          fire,water
         2 3,6,9                          fire,ice,water

SQL>

答案 1 :(得分:1)

您可以尝试以下操作:

我使用了该表,因为我需要一些值才能获得不同的值。这里我用过ROWID

SELECT
    ID,
    LISTAGG(NUM, ',') WITHIN GROUP(
        ORDER BY
            NUM
    ) AS NUM,
    LISTAGG(POW, ',') WITHIN GROUP(
        ORDER BY
            POW
    ) AS POW
FROM
    (
        SELECT
            DISTINCT ROWID,
            ID,
            REGEXP_SUBSTR(NUM, '[^,]+', 1, LEVEL) NUM,
            REGEXP_SUBSTR(POW, '[^,]+', 1, LEVEL) POW
        FROM
            TEST
        CONNECT BY REGEXP_SUBSTR(NUM, '[^,]+', 1, LEVEL) IS NOT NULL
                   OR REGEXP_SUBSTR(POW, '[^,]+', 1, LEVEL) IS NOT NULL
    )
    GROUP BY ID
    ORDER BY ID;

db<>fiddle demo

干杯!

---- 更新 ----

正如评论中提到的那样,它正在生成重复项,我对整个查询进行了如下重新构架:

SELECT
    ID,
    LISTAGG(C_S.NUM, ',') WITHIN GROUP(
                ORDER BY
                    C_S.NUM
            ) AS NUM,
    LISTAGG(C_S.POW, ',') WITHIN GROUP(
                ORDER BY
                    C_S.POW
            ) AS POW
FROM
(SELECT
    T.ID,
    REGEXP_SUBSTR(T.NUM, '[^,]+', 1, NUMS_COMMA.COLUMN_VALUE) NUM,
    REGEXP_SUBSTR(T.POW, '[^,]+', 1, NUMS_COMMA.COLUMN_VALUE) POW
FROM
    TEST T,
    TABLE ( CAST(MULTISET(
        SELECT
            LEVEL
        FROM
            DUAL
        CONNECT BY
            LEVEL <= GREATEST(LENGTH(REGEXP_REPLACE(T.NUM, '[^,]+')),
            LENGTH(REGEXP_REPLACE(T.POW, '[^,]+'))) + 1
    ) AS SYS.ODCINUMBERLIST) ) NUMS_COMMA) C_S
 GROUP BY ID;

db<>fiddle demo updated

干杯!

答案 2 :(得分:1)

Oracle设置

CREATE TABLE test_data ( Numbers, Powers ) AS
SELECT '4,5,1', 'WATER,FIRE'     FROM DUAL UNION ALL
SELECT '6,3,9', 'ICE,WATER,FIRE' FROM DUAL UNION ALL
SELECT '7',     'D,B,E,C,A'      FROM DUAL

查询

SELECT (
         SELECT LISTAGG( TO_NUMBER( REGEXP_SUBSTR( t.numbers, '\d+', 1, LEVEL ) ), ',' )
                  WITHIN GROUP ( ORDER BY TO_NUMBER( REGEXP_SUBSTR( t.numbers, '\d+', 1, LEVEL ) ) )
         FROM   DUAL
         CONNECT BY LEVEL <= REGEXP_COUNT( t.numbers, ',' ) + 1
       ) AS numbers,
       (
         SELECT LISTAGG( REGEXP_SUBSTR( t.powers, '[^,]+', 1, LEVEL ), ',' )
                  WITHIN GROUP ( ORDER BY REGEXP_SUBSTR( t.powers, '[^,]+', 1, LEVEL ) )
         FROM   DUAL
         CONNECT BY LEVEL <= REGEXP_COUNT( t.powers, ',' ) + 1
       ) AS numbers
FROM   test_data t

输出

NUMBERS | NUMBERS       
:------ | :-------------
1,4,5   | FIRE,WATER    
3,6,9   | FIRE,ICE,WATER
7       | A,B,C,D,E     

db <>提琴here