Mar*_*ber 6 sql oracle r distinct-values
我有一个唯一的字符串列表(最初的想法是表中的列名).任务是执行列表的最大可能缩写,因此列表保持不同.
例如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;
Run Code Online (Sandbox Code Playgroud)
预期的结果是
COL ABR_COL
------ ------------------------
AAA AAA
AAAAAA AAAA
AABA AAB
AB AB
BAAAA BA
BBAA BB
COL1 COL1
COL21 COL2
Run Code Online (Sandbox Code Playgroud)
我管理了一个由四个子查询组成的强力解决方案,我没有故意发布,因为我希望有一个更简单的解决方案,我不想分散注意力.
顺便说一句,在r调用中有一个类似的函数abbreviate,但我正在寻找SQL解决方案.首选Oracle为其他RDBMS解决方案welcommed.
我会在递归 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, 1, 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
Run Code Online (Sandbox Code Playgroud)
这是一个 db<>fiddle。
这lev是完全没有必要的。您可以length(abbr) desc在order by. 但是,当我使用递归 CTE 时,我通常会包含一个递归计数器,所以这是习惯。
在 CTE 中进行额外的比较可能看起来更复杂,但它简化了执行——递归在正确的值处停止。
这也针对唯一的单字母col值进行了测试。
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |