查找字符串中出现次数最多的字符

Bar*_*Das 4 sql oracle

使用Oracle SQL查询,我们可以执行以下操作吗?

      Input       Output
    'aaaabcd' --->  'a'
    '0001001' --->  '0'
Run Code Online (Sandbox Code Playgroud)

也就是说,找到字符串中出现次数最多的字符?

Dav*_*ber 6

是的,这可以通过使用CONNECT BY.但有点复杂:

SELECT xchar, xcount FROM (
    SELECT xchar, COUNT(*) AS xcount, RANK() OVER ( ORDER BY COUNT(*) DESC) AS rn
      FROM (
        SELECT SUBSTR('aaaabcd', LEVEL, 1) AS xchar
          FROM dual
       CONNECT BY LEVEL <= LENGTH('aaaabcd')
   ) GROUP BY xchar
) WHERE rn = 1;
Run Code Online (Sandbox Code Playgroud)

我们在最里面的查询中做的是将字符串分解为单个字符.然后我们只是COUNT()按字符分组,并RANK()用来查找最大值(请注意,如果最常出现的字符存在平局,则会返回多个结果).

上面的查询返回最常出现的字符及其出现的次数.

如果您有一个包含多个字符串的表,那么您将需要执行以下操作:

WITH strlen AS (
  SELECT LEVEL AS strind
    FROM dual
 CONNECT BY LEVEL <= 30
)
SELECT id, xchar, xcount FROM (
    SELECT id, xchar, COUNT(*) AS xcount, RANK() OVER ( PARTITION BY id ORDER BY COUNT(*) DESC) AS rn
      FROM (
        SELECT s.id, SUBSTR(s.str, sl.strind, 1) AS xchar
          FROM strings s, strlen sl
         WHERE LENGTH(s.str) >= sl.strind
   ) GROUP BY id, xchar
) WHERE rn = 1;
Run Code Online (Sandbox Code Playgroud)

其中30一个幻数等于最长字符串的长度,或更大.请参见SQL小提琴.或者,您可以执行以下操作以避免幻数:

WITH strlen AS (
  SELECT LEVEL AS strind
    FROM dual
 CONNECT BY LEVEL <= ( SELECT MAX(LENGTH(str)) FROM strings )
)
SELECT id, xchar, xcount FROM (
    SELECT id, xchar, COUNT(*) AS xcount, RANK() OVER ( PARTITION BY id ORDER BY COUNT(*) DESC) AS rn
      FROM (
        SELECT s.id, SUBSTR(s.str, sl.strind, 1) AS xchar
          FROM strings s, strlen sl
         WHERE LENGTH(s.str) >= sl.strind
   ) GROUP BY id, xchar
) WHERE rn = 1;
Run Code Online (Sandbox Code Playgroud)

更新了SQL小提琴.