我想在Oracle查询中找到varchar2(字符串中)中最长的单词。在某些情况下,我会将字符串拆分为表中的单独单词,然后聚合函数可以解决它(例如,一旦我有max(长度(my_field)我可以追踪最长的单词)。
但在这种情况下,我没有那么奢侈。所以我需要计算一个没有聚合的字符串中最长的单词。
我找到了一种方法来使用REGEXP_REPLACE来查找长于N个字符的单词。这还不错。但我没有看到使用正则表达式或任何其他函数找到最长单词的方法。
这是我用来查找超过4个字符的单词的简化版本:
select
regexp_replace(
' a cd efg hijk lmnop qrst uvw xy z '
, '([^[:alnum:]][[:alnum:]]{1,3}[^[:alnum:]])'
, ' '
, 1
, 0
) x
from dual;
但我怎么能只返回最长的单词呢?
答案 0 :(得分:0)
编辑:对不起,我没有完全读懂你的意图。因此,出于某种原因,您无法使用聚合函数,以下解决方案仅供参考。最好的关注!
WITH tmp AS
(
SELECT
regexp_substr(' a cd efg hijk lmnop qrst uvw xy z ','[^ ]+', 1, level) col
FROM
dual
CONNECT BY
regexp_substr(' a cd efg hijk lmnop qrst uvw xy z ', '[^ ]+', 1, level) IS NOT NULL
)
SELECT
col
FROM
tmp
WHERE
length(col) = (SELECT MAX(length(col) ) FROM tmp);
答案 1 :(得分:0)
如果我理解得很清楚,你需要一种方法从给定的字符串中提取最长的单词(一个或多个)而不使用任何表来存储数据。
如果是这样,这可能是一种方式:
with test(s) as ( select ' a cd efg hijk lmnop qrst uvw xy z LMNOP' from dual)
select word
from (
select regexp_substr(s, '[^ ]+', 1, level) as word,
rank() over ( partition by 1 order by length(regexp_substr(s, '[^ ]+', 1, level)) desc) as rank
from test
connect by regexp_instr(s, '[^ ]+', 1, level) > 0
)
where rank = 1
WORD
----------
lmnop
LMNOP
内部查询使用常用方法来拆分字符串,然后使用rank
根据字的长度评估每一行:
with test(s) as ( select ' a cd efg hijk lmnop qrst uvw xy z LMNOP' from dual)
select regexp_substr(s, '[^ ]+', 1, level) as word,
rank() over ( partition by 1 order by length(regexp_substr(s, '[^ ]+', 1, level)) desc) as rank
from test
connect by regexp_instr(s, '[^ ]+', 1, level) > 0
WORD RANK
---------- ----------
lmnop 1
LMNOP 1
hijk 3
qrst 3
efg 5
uvw 5
xy 7
cd 7
z 9
a 9
外部部分只是过滤结果,只获得排名最高的单词,即最长的单词。
这适用于您有多个具有最大长度的单词,并且基于输入字符串采用您发布的格式的假设;例如,如果您添加逗号来分隔单词,则会将其视为单词的一部分。