通过 Oracle SQL 返回输入字符串中出现的最大字符
Posted
技术标签:
【中文标题】通过 Oracle SQL 返回输入字符串中出现的最大字符【英文标题】:Return maximum occurring character in an input string though Oracle SQL 【发布时间】:2021-12-29 10:53:44 【问题描述】:如果我有水果名称,如木瓜、橙子等,请逐行说明...
如何找到每个字符串中出现的最大字符。 对于木瓜,它将是“a”,因为它重复了 3 次 对于橙色,它将是所有字符,因为每个字符只重复一次 我需要使用 Oracle SQL 解决上述查询
【问题讨论】:
这能回答你的问题吗? How to count the number of occurrences of a character in an Oracle varchar value? 不..我需要找到字符的最大出现次数。在那个问题中,事先提到要找到特定字符的字符总数。但在这个问题中,我需要找到包含最多时间的字符 【参考方案1】:这是一种选择:
SQL> WITH
2 fruit (name)
3 AS
4 (SELECT 'Papaya' FROM DUAL
5 UNION ALL
6 SELECT 'Orange' FROM DUAL),
7 temp
8 AS
9 (SELECT name, SUBSTR (name, COLUMN_VALUE, 1) letter
10 FROM fruit
11 CROSS JOIN
12 TABLE (
13 CAST (
14 MULTISET ( SELECT LEVEL
15 FROM DUAL
16 CONNECT BY LEVEL <= LENGTH (name))
17 AS SYS.odcinumberlist))),
18 temp2
19 AS
20 ( SELECT name,
21 letter,
22 COUNT (*) cnt,
23 RANK () OVER (PARTITION BY name ORDER BY COUNT (*) DESC) rnk
24 FROM temp
25 GROUP BY name, letter)
26 SELECT name,
27 LISTAGG (letter, ', ') WITHIN GROUP (ORDER BY letter) letters,
28 cnt
29 FROM temp2
30 WHERE rnk = 1
31 GROUP BY name, cnt;
NAME LETTERS CNT
------ -------------------- ----------
Orange O, a, e, g, n, r 1
Papaya a 3
SQL>
TEMP
CTE 将名称拆分为行(按每个字母)
TEMP2
按数量降序排列
final select
返回排名“最高”的字母
【讨论】:
谢谢伙计!!有没有其他方法可以用不同的方法解决这个查询? 不客气。像往常一样,同样的问题可以用不同的方式解决。我建议了我认为最合适的一个。我想不出比这更好的了。【参考方案2】:我有另一个想法。
当数据如下。
create table t as
select 'Papaya' w from dual union all
select 'Orange' w from dual union all
select 'Baby' w from dual union all
select 'CocaCola' w from dual
获取字母表的最大出现次数并计数如下
with cte as (
select w, az.c find, regexp_count(w, az.c, 1, 'i') cnt
from t,
(select chr(rownum + 96) c
from dual
connect by rownum <= 26
) az
),
cte2 as (
select w, max(lpad(cnt, 10, '0') || find) cnt_find
from cte
group by w
)
select w, substr(cnt_find, 11, 999) find, to_number(substr(cnt_find, 1, 10)) cnt
from cte2
结果:
| W | FIND | CNT |
|----------|------|----:|
| Orange | r | 1 |
| Papaya | a | 3 |
| Baby | b | 2 |
| CocaCola | c | 3 |
由于字母集限制为 26 种,我生成了 26 行与单词表交叉连接。
select chr(rownum + 96) c
from dual
connect by rownum <= 26
并使用 regexp_count 获取每个字母的出现次数。
select w, az.c find, regexp_count(w, az.c, 1, 'i') cnt
并检索最大出现次数,然后是按单词分组的字母表。 (lpad 用于填充 10 长度以供所有出现使用 substr 下一步)
select w, max(lpad(cnt, 10, '0') || find) cnt_find
from cte
group by w
并划分出现次数和字母的最大值。 (substr 是 1 到 10,而 11 到 end,因为所有最大出现的长度都是 10)
select w, substr(cnt_find, 11, 999) find, to_number(substr(cnt_find, 1, 10)) cnt
from cte2
此链接详细显示了我是如何进行此查询的。
https://dbfiddle.uk/?rdbms=oracle_18&fiddle=29516e70a1270c4035d7165832905777
显示所有获胜者而不是第一个获胜者
with cte as (
select w, az.c find, regexp_count(w, az.c, 1, 'i') cnt
from t,
(select chr(rownum + 96) c
from dual
connect by rownum <= 26
) az
), rank_t as
(
select w, find, cnt,
rank() over (partition by w order by cnt desc) rank_cnt
from cte
)
select w,
listagg(find, ', ') within group (order by w) find_list,
max(cnt) max_cnt
from rank_t
where rank_cnt = 1
group by w
结果:
| W | FIND_LIST | MAX_CNT |
|----------|------------------|--------:|
| Baby | b | 2 |
| CocaCola | c | 3 |
| Orange | a, e, g, n, o, r | 1 |
| Papaya | a | 3 |
以前的版本只显示最大的一个最大出现次数。所以我使用 rank 函数将所有最大出现次数设为 1
select w, find, cnt,
rank() over (partition by w order by cnt desc) rank_cnt
from cte
只过滤数字 1 并将行转换为带有 listagg 的列
select w,
listagg(find, ', ') within group (order by w) find_list,
max(cnt) max_cnt
from rank_t
where rank_cnt = 1
group by w
第二个链接详细显示了我是如何进行此查询的。
https://dbfiddle.uk/?rdbms=oracle_18&fiddle=c0c15ccb9974d0c4fd14a34408f69fb7
【讨论】:
嘿伙计...感谢您的解决方案。它也可以正常工作,但是说当存在诸如“橙色”之类的字符串并且所有字符都是唯一的时,第二列仅返回一个字符而不是所有字符,因为所有字符的最大出现次数为 1 个值。然后,您提供的数据也将按预期工作。再次感谢!!! @SSaha 你说得对,我附加了“橙色”大小写。以上是关于通过 Oracle SQL 返回输入字符串中出现的最大字符的主要内容,如果未能解决你的问题,请参考以下文章