使用T-SQL查找最后一次出现的子字符串的索引

Raj*_*Raj 116 t-sql sql-server string search sql-server-2000

有没有一种直接的方法来使用SQL查找最后一次出现的字符串的索引?我现在正在使用SQL Server 2000.我基本上需要.NET System.String.LastIndexOf方法提供的功能.一个小的谷歌搜索透露了这个 - 函数来检索最后一个索引 - 但如果你传入一个"文本"列表达式,这不起作用.在其他地方找到的其他解决方案只有在您搜索的文本长度为1个字符时才起作用.

我可能不得不做一个功能.如果我这样做,我会在这里发布,所以你们大家可以看看它,也许可以利用它.

Phi*_*ley 167

直截了当的方式?不,但我已经反过来了.从字面上看.

在先前的例程中,为了找到给定字符串的最后一次出现,我使用了REVERSE()函数,然后是CHARINDEX,再次使用REVERSE来恢复原始顺序.例如:

SELECT
   mf.name
  ,mf.physical_name
  ,reverse(left(reverse(physical_name), charindex('\', reverse(physical_name)) -1))
 from sys.master_files mf
Run Code Online (Sandbox Code Playgroud)

显示如何从"物理名称"中提取实际数据库文件名,无论嵌套在子文件夹中有多深.这只会搜索一个字符(反斜杠),但您可以在此基础上搜索更长的搜索字符串.

唯一的缺点是,我不知道这对TEXT数据类型有多好.我已经在SQL 2005上工作了几年,并且不再熟悉使用TEXT了 - 但我似乎记得你可以使用LEFT和RIGHT吗?

菲利普

  • 好一个!我根据自己的需要进行了修改:email.Substring(0,email.lastIndexOf('@'))== SELECT LEFT(电子邮件,LEN(电子邮件)-CHARINDEX('@',REVERSE(电子邮件))) (4认同)
  • 您是否在SQL Server 2000中的文本字段上尝试过REVERSE? (2认同)

小智 97

最简单的方法是....

REVERSE(SUBSTRING(REVERSE([field]),0,CHARINDEX('[expr]',REVERSE([field]))))
Run Code Online (Sandbox Code Playgroud)

  • 如果你的`[expr]`超过1个符号,你也需要反转它! (10认同)
  • +1因为如果没有找到匹配项,则会出现"无效长度参数传递给LEFT或SUBSTRING函数"等错误 (2认同)

Bin*_*ony 53

如果您使用的是Sqlserver 2005或更高版本,REVERSE多次使用函数会对性能产生不利影响,下面的代码会更有效.

DECLARE @FilePath VARCHAR(50) = 'My\Super\Long\String\With\Long\Words'
DECLARE @FindChar VARCHAR(1) = '\'

-- Shows text before last slash
SELECT LEFT(@FilePath, LEN(@FilePath) - CHARINDEX(@FindChar,REVERSE(@FilePath))) AS Before
-- Shows text after last slash
SELECT RIGHT(@FilePath, CHARINDEX(@FindChar,REVERSE(@FilePath))-1) AS After
-- Shows the position of the last slash
SELECT LEN(@FilePath) - CHARINDEX(@FindChar,REVERSE(@FilePath)) AS LastOccuredAt
Run Code Online (Sandbox Code Playgroud)

  • 这个答案值得更多关注.做得好. (5认同)
  • 事后看来,这似乎是显而易见的,但如果您要搜索字符串而不是单个字符,则必须执行以下操作:LEN(@FilePath) - CHARINDEX(REVERSE(@FindString),REVERSE(@FilePath)) (2认同)

gbn*_*gbn 29

您仅限于文本数据类型的小功能列表.

我所能建议的只是开始PATINDEX,但是从DATALENGTH-1, DATALENGTH-2, DATALENGTH-3等到后工作直到你得到一个结果或最终为零(DATALENGTH-DATALENGTH)

这真的是SQL Server 2000根本无法处理的事情.

编辑其他答案:REVERSE不在SQL Server 2000中可与文本数据一起使用的函数列表中


小智 14

DECLARE @FilePath VARCHAR(50) = 'My\Super\Long\String\With\Long\Words'
DECLARE @FindChar VARCHAR(1) = '\'

SELECT LEN(@FilePath) - CHARINDEX(@FindChar,REVERSE(@FilePath)) AS LastOccuredAt
Run Code Online (Sandbox Code Playgroud)


小智 7

旧的,但仍然有效的问题,所以我基于其他人在这里提供的信息创建了我.

create function fnLastIndexOf(@text varChar(max),@char varchar(1))
returns int
as
begin
return len(@text) - charindex(@char, reverse(@text)) -1
end
Run Code Online (Sandbox Code Playgroud)


小智 7

这对我很有用.

REVERSE(SUBSTRING(REVERSE([field]), CHARINDEX(REVERSE('[expr]'), REVERSE([field])) + DATALENGTH('[expr]'), DATALENGTH([field])))
Run Code Online (Sandbox Code Playgroud)


小智 6

嗯,我知道这是一个旧线程,但统计表可以在 SQL2000(或任何其他数据库)中执行此操作:

DECLARE @str CHAR(21),
        @delim CHAR(1)
 SELECT @str = 'Your-delimited-string',
        @delim = '-'

SELECT
    MAX(n) As 'position'
FROM
    dbo._Tally
WHERE
    substring(@str, _Tally.n, 1) = @delim
Run Code Online (Sandbox Code Playgroud)

统计表只是一个递增数字的表。

获取substring(@str, _Tally.n, 1) = @delim每个分隔符的位置,然后您只需获取该集合中的最大位置。

统计表很棒。如果您以前没有使用过它们,可以阅读一篇关于SQL Server Central的好文章。

*编辑:已删除n <= LEN(TEXT_FIELD),因为您不能在 TEXT 类型上使用 LEN() 。只要substring(...) = @delim仍然存在,结果仍然是正确的。


小智 6

REVERSE(SUBSTRING(REVERSE(ap_description),CHARINDEX('.',REVERSE(ap_description)),len(ap_description)))  
Run Code Online (Sandbox Code Playgroud)

为我工作得更好