对逗号分隔值进行计数和排序

时间:2021-07-25 17:22:52

标签: sql oracle

我有下面的一列“表格”(为数据模型道歉,不是我的错:():

COL_IN
------
2K, E
E, 2K
O

我想获得以下输出,按计数降序排列:

COL_OUT COUNT
----------
K   4
E   2
O   1

2 个答案:

答案 0 :(得分:2)

您可以以这样的方式使用分层查询

WITH t2 AS
(
   SELECT TRIM(REGEXP_SUBSTR(col_in,'[^,]+',1,level)) AS s
     FROM t
  CONNECT BY level <= REGEXP_COUNT(col_in,',')+1 
      AND PRIOR SYS_GUID() IS NOT NULL
      AND PRIOR col_in = col_in
)
SELECT REGEXP_SUBSTR(s,'[^0-9]') AS col_out,
       SUM(NVL(REGEXP_SUBSTR(s,'[^[:alpha:]]'),1)) AS count
  FROM t2
 GROUP BY REGEXP_SUBSTR(s,'[^0-9]'),REGEXP_SUBSTR(s,'[^[:alpha:]]')
 ORDER BY count DESC  
  

假设所有数据都是字母数字(例如,不包含特殊字符,如 $,#,! ..etc.)

答案 1 :(得分:2)

COUNT 是保留关键字,因此它不是一个好的列名 - 即使在最终输出中也是如此。我改用 COUNT_(带下划线)。

除此之外,您可以修改输入字符串,使它们成为有效的 JSON 数组,然后您就可以使用 JSON 函数来拆分它们。将字符串拆分为标记后,将前导数字(如果存在)与字符串的其余部分分开并进行聚合是一件简单的事情。总和中的 NVL 为每个没有前导整数的标记加 1。

仅包含用于测试的示例数据(如果您有实际表,请删除顶部的 WITH 子句):

with
  tbl (col_in) as (
    select '2K, E' from dual union all
    select 'E, 2K' from dual union all
    select 'O'     from dual
  )
select ltrim(col, '0123456789') as col_out
     , sum(nvl(to_number(regexp_substr(col, '^\d*')), 1)) as count_
from   tbl,
       json_table('["' || regexp_replace(col_in, ', *', '","') || '"]', '$[*]'
            columns col path '$')
group  by ltrim(col, '0123456789')
order  by count_ desc, col_out
;

COL_OUT COUNT_
------- ------
K            4
E            2
O            1