sql – 保持唯一的字符串的缩写

前端之家收集整理的这篇文章主要介绍了sql – 保持唯一的字符串的缩写前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个唯一的字符串列表(最初的想法是表中的列名).
任务是执行列表的最大可能缩写,因此列表保持不同.

例如AAA,AB可以缩写为AA,AB. (但不是A,AB – 因为A可能是AAA和AB的前缀).
AAAA,BAAAA可缩短为A,B.
但是A1,A2根本不能缩写.

以下是示例数据

create table tab as 
select 'AAA' col from dual union all
select 'AABA' col from dual union all
select 'COL1' col from dual union all
select 'COL21' col from dual union all
select 'AAAAAA' col from dual union all
select 'BBAA' col from dual union all
select 'BAAAA' col from dual union all
select 'AB' col from dual;

预期的结果是

COL    ABR_COL                
------ ------------------------
AAA    AAA                      
AAAAAA AAAA                     
AABA   AAB                      
AB     AB                       
BAAAA  BA                       
BBAA   BB                       
COL1   COL1                     
COL21  COL2

我管理了一个由四个子查询组成的强力解决方案,我没有故意发布,因为我希望有一个更简单的解决方案,我不想分散注意力.

顺便说一句,在r中有一个类似的函数,叫做abbreviate,但我正在寻找sql解决方案.其他RDBMS的首选Oracle解决方案受到欢迎.

解决方法

我会在递归CTE中进行过滤:
with potential_abbreviations(col,abbr,lev) as (
      select col,col as abbr,1 as lev
      from tab
      union all
      select pa.col,substr(pa.abbr,1,length(pa.abbr) - 1) as abbr,lev + 1
      from potential_abbreviations pa
      where length(abbr) > 1 and
            not exists (select 1
                        from tab
                        where tab.col like substr(pa.abbr,length(pa.abbr) - 1) || '%' and
                              tab.col <> pa.col
                       )
     )
select pa.col,pa.abbr
from (select pa.*,row_number() over (partition by pa.col order by pa.lev desc) as seqnum
      from potential_abbreviations pa
     ) pa
where seqnum = 1

Here是db<>小提琴.

严格来说,没有必要.您可以按顺序使用length(abbr)desc.但是,当我使用递归CTE时,我通常会包含一个递归计数器,所以这就是习惯.

在CTE中进行额外的比较可能看起来更复杂,但它简化了执行 – 递归停止在正确的值.

这也是在唯一的单字母col值上测试的.

原文链接:https://www.f2er.com/mssql/74748.html

猜你在找的MsSQL相关文章