在SQL的一列(整个列)中按字母顺序对用逗号按字母顺序分隔的字符串/单词进行排序

时间:2018-08-29 13:12:33

标签: sql oracle

让我们说我有一张表中的以下数据: (像这样的1000余行)

Bird  
----------------------------
Sparrow, Eagle, Crow
Woodpecker, Sparrow
Crow, Eagle                     
etc. etc.

我希望最后一列按字母顺序排序。像这样:

Bird  
--------------------
Crow, Eagle, Sparrow
Sparrow, Woodpecker   
Crow, Eagle                    
etc. etc.

需要知道可以执行此操作的SQL查询。可能是SQL Developer。

1 个答案:

答案 0 :(得分:3)

这是使用公用表表达式(CTE)来解决问题的Oracle解决方案。不确定这是否有帮助,但也许会为您提供一个想法或一个可以应用于您的环境的起点。

SQL> -- Set up original data set
SQL> with bird_tbl(id, unsorted_list) as (
     select 1, 'Sparrow, Eagle, Crow' from dual union all
     select 2, 'Woodpecker, Sparrow' from dual union all
     select 3, 'Crow, Eagle' from dual
   ),
   -- Split the list into a row for each element
   split_tbl(id, bird) as (
     select id, regexp_substr(unsorted_list, '(.*?)(, |$)', 1, level, null, 1)
     from bird_tbl
     connect by level <= regexp_count(unsorted_list, ', ')+1
       and prior id = id
       and prior sys_guid() is not null
   )
   -- select * from split_tbl;
   -- Rebuild the sorted row
   select id, listagg(bird, ', ')
     within group (order by bird) sorted_list
     from split_tbl
     group by id;

        ID SORTED_LIST
---------- --------------------
         1 Crow, Eagle, Sparrow
         2 Sparrow, Woodpecker
         3 Crow, Eagle

编辑:这是适用于您的情况的方法。只需将<your_primary_key>替换为主键列名,将<your_column_name>替换为包含未排序列表的列名,将<your_table_name>替换为表名。

with split_tbl(<your_primary_key>, <your_column_name>) as (
     select <your_primary_key>, regexp_substr(<your_column_name>, '(.*?)(, |$)', 1, level, null, 1)
     from <your_table_name>
     connect by level <= regexp_count(<your_column_name>, ', ')+1
       and prior <your_primary_key> = <your_primary_key>
       and prior sys_guid() is not null
   )
   -- select * from split_tbl;
   -- Rebuild the sorted row
   select <your_primary_key>, listagg(<your_column_name>, ', ')
     within group (order by <your_column_name>) sorted_list
     from split_tbl
     group by <your_primary_key>;