Sql Oracle 11g-找到一个新的独特值

Sql Oracle 11g-找到一个新的独特值,sql,oracle11g,Sql,Oracle11g,我有一个用户表,其中一列是User_ID(命名策略=名字的第一个字母,其余是姓氏。如果存在名称,则按1递增) 例如: John Doe->user_id=jdoe 如果jdoe已经存在,那么user_id=jdoe1 查询的输入是一个基本的用户id(例如jdoe) 我想扫描这个表,查询的输出是一个新的用户id值 如果表格具有以下值: jdoe jdoe1 jdoe2 jdoe3 输出应该是jdoe4 任何帮助都将不胜感激 谢谢 附言 不允许对表进行更改 查询中的值正用于另一个系统(active

我有一个用户表,其中一列是User_ID(命名策略=名字的第一个字母,其余是姓氏。如果存在名称,则按1递增)

例如: John Doe->user_id=jdoe

如果jdoe已经存在,那么user_id=jdoe1

查询的输入是一个基本的用户id(例如jdoe) 我想扫描这个表,查询的输出是一个新的用户id值

如果表格具有以下值:

jdoe
jdoe1
jdoe2
jdoe3
输出应该是
jdoe4

任何帮助都将不胜感激

谢谢

附言

不允许对表进行更改


查询中的值正用于另一个系统(active directory)

编辑:这将根据来自的注释进行更正。假设基本名称/首字母不包含数字

WITH tab
     AS (SELECT 'jdoe' name FROM DUAL
         UNION ALL
         SELECT 'jdoe1' FROM DUAL
         UNION ALL
         SELECT 'jdoe2' FROM DUAL
         UNION ALL
         SELECT 'jdoe3' FROM DUAL
         UNION ALL
         SELECT 'jdoes7' FROM DUAL
         UNION ALL
         SELECT 'jjdoe66' FROM DUAL)

SELECT :newName || TO_CHAR (MAX (id) + 1)
  FROM (SELECT NVL (REGEXP_REPLACE (name, '[^0-9]'), 0) id
          FROM tab
         WHERE REGEXP_LIKE (name, '^' || :newName || '[0-9]'));
REGEXP\u将
替换为
[^0-9]
删除所有非数字字符

REGEXP\u LIKE
with
[0-9]
仅显示与以下数字匹配的项<代码>^表示在的开头


:newName
是一个绑定变量。

它使用一个内联视图来获取
用户id
和与基本id值匹配的任何事物的数字后缀,然后决定是否可以使用未加修饰的基本值(如果
max(user\u id)
为空,则没有类似的内容),如果不是,则添加递增的后缀

该后缀基于现有的最高后缀,但如果到目前为止您只有基本名称(
jdoe
没有数字),那么
max(suffix)
为空,因此
nvl()
在添加一个后缀之前将其转换为零

select decode(max(user_id), null, :base, :base || (nvl(max(suffix), 0) + 1))
  as new_user_id
from (
  select user_id, regexp_replace(user_id, '^[[:alpha:]]*', null) as suffix
  from users
  where regexp_like(user_id, '^' || :base || '[^[:alpha:]]*$')
);
具有包含以下内容的起始用户表:

jdoe   
jdoe1  
jdoe2  
jdoe3  
jdoes6 
adoe   
。。。更改bind变量以提供基本字符串将为您提供:

jdoe -> jdoe4
jdoes -> jdoes7
adoe -> adoe1
adoes -> adoes

concat count(*)+1 etcIf您
count
任何删除都将允许DUP,从regexp\u substr中选择int的最大值,这将匹配更长的名称-因此,如果您有
jdoes6
,这将返回
jdoe7
,而不是
jdoe4
。您可以使用
避免这种情况,其中regexp|u喜欢(name,“^”|:newName | |”[^[:alpha:]*$)
。但它也不会为第一个副本提供附加的1;如果只有
jdoe
存在,它将再次返回
jdoe
,而不是
jdoe1