如何找到行之间在oracle中常见的最长子串?

时间:2018-09-26 09:34:10

标签: oracle stored-procedures

在我的oracle数据库中,我想找到最长的公用子字符串。 示例:

\roomname\nameid\department\foledertest\foldername\a.txt
\roomname\nameid\department\foledertest\foldername\forlder1\a.txt
\roomname\nameid\department\foledertest\foldername\forlder1\folder2\a.txt

所以我想要的结果是:

\roomname\nameid\department\foledertest\foldername\

有人有主意帮助我吗,谢谢?

2 个答案:

答案 0 :(得分:2)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE files ( name ) AS
SELECT '\roomname\nameid\department\foledertest\foldername\a.txt' FROM DUAL UNION ALL
SELECT '\roomname\nameid\department\foledertest\foldername\forlder1\a.txt' FROM DUAL UNION ALL
SELECT '\roomname\nameid\department\foledertest\foldername\forlder1\folder2\a.txt' FROM DUAL;

查询1

WITH names ( name ) AS (
  SELECT SUBSTR( name, 1, MIN( LENGTH( name ) ) OVER () )
  FROM   files
),
substrs ( common, num_matches ) AS (
  SELECT name,
         COUNT( DISTINCT name ) OVER ()     
  FROM   names
UNION ALL
  SELECT SUBSTR( common, 1, LENGTH( common ) - 1 ),
         COUNT( DISTINCT SUBSTR( common, 1, LENGTH( common ) - 1 )  ) OVER ()     
  FROM   substrs
  WHERE  num_matches > 1
  AND    LENGTH( common ) > 1
)
SELECT common
FROM   substrs
WHERE  num_matches = 1
AND    ROWNUM = 1

Results

|                                              COMMON |
|-----------------------------------------------------|
| \roomname\nameid\department\foledertest\foldername\ |

更新-如果要限制它完成子文件夹,则将输出截断为最后一个\字符:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE files ( name ) AS
SELECT '\roomname\nameid\department\foledertest\foldername\a.txt' FROM DUAL UNION ALL
SELECT '\roomname\nameid\department\foledertest\foldername\forlder1\a.txt' FROM DUAL UNION ALL
SELECT '\roomname\nameid\department\foledertest\foldername\forlder1\folder2\a.txt' FROM DUAL UNION ALL
SELECT '\roomname\nameid\department\foledertest\foldername_1\a.txt' FROM DUAL;

查询1

WITH names ( name ) AS (
  SELECT SUBSTR( name, 1, MIN( LENGTH( name ) ) OVER () )
  FROM   files
),
substrs ( common, num_matches ) AS (
  SELECT name,
         COUNT( DISTINCT name ) OVER ()     
  FROM   names
UNION ALL
  SELECT SUBSTR( common, 1, LENGTH( common ) - 1 ),
         COUNT( DISTINCT SUBSTR( common, 1, LENGTH( common ) - 1 )  ) OVER ()     
  FROM   substrs
  WHERE  num_matches > 1
  AND    LENGTH( common ) > 1
)
SELECT SUBSTR( common, 1, INSTR( common, '\', -1 ) ) AS common
FROM   substrs
WHERE  num_matches = 1
AND    ROWNUM = 1

Results

|                                   COMMON |
|------------------------------------------|
| \roomname\nameid\department\foledertest\ |

答案 1 :(得分:0)

您可以使用stats_mode函数,该函数将一组值作为其参数,并返回出现频率最高的值:

select stats_mode(field_name) 
  from table_name

返回

\roomname\nameid\department\foledertest\foldername\a.txt

然后,在这种情况下,您可以使用诸如子字符串函数之类的方法仅捕获路径:

select substr(common, 1, instr(common, '\', -1))
  from (select stats_mode(field_name) as common 
          from table_name);