使用Oracle SQL查询,我们可以执行以下操作吗?
Input Output
'aaaabcd' ---> 'a'
'0001001' ---> '0'
Run Code Online (Sandbox Code Playgroud)
也就是说,找到字符串中出现次数最多的字符?
是的,这可以通过使用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)