【问题标题】:Find the longest word in a string using Oracle SQL使用 Oracle SQL 查找字符串中最长的单词
【发布时间】:2017-07-04 22:48:07
【问题描述】:

我想在 Oracle 查询中查找 varchar2(在字符串中)中最长的单词。在某些情况下,我会将字符串拆分为表格中的单独单词,然后聚合函数可以解决它(例如,一旦我有 max(length(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;

但是我怎样才能只返回最长的单词呢?

【问题讨论】:

  • 我只能想到使用子字符串作为正则表达式很难。
  • 如果您打算在不使用 PL/SQL 的情况下将字符串拆分为单词,这可能是您唯一的选择。
  • 这还不清楚。如果超过一个单词并列最长,您要全部返回吗?如果您的字符串具有相同长度的所有单词,比如说 7 个字符 - 如果不是在单独的行中,您如何建议“返回”它们?所以你不必把绳子分开吗?你说的“没有那种奢侈”是什么意思?哪种奢侈品?

标签: sql regex oracle


【解决方案1】:

已编辑:抱歉,我没有完全阅读您的意图。因此,在您的情况下,由于某种原因您无法使用聚合函数,以下解决方案仅供参考。最好的问候!

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);

【讨论】:

    【解决方案2】:

    如果我理解得很好,您需要一种方法来从给定字符串中提取最长的单词(一个或多个),而不使用任何表来存储数据。

    如果是这样,这可能是一种方式:

    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
    

    外部部分只是简单地过滤结果,只得到排名靠前的单词的行,即最长的单词。

    这适用于您有多个单词的顶部长度,并且基于输入字符串采用您发布的格式的假设;例如,如果您添加逗号来分隔单词,它将被视为单词的一部分。

    【讨论】:

      猜你喜欢
      • 2015-05-21
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      • 2015-04-23
      • 1970-01-01
      • 2021-05-23
      相关资源
      最近更新 更多