拆分字符串并取最后一个元素

59

我有一个包含以下数值的表格:

Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx
OurStory/MeettheFoodieandtheMD.aspx
TheFood/OurMenu.aspx

我想获得这个

Diet.aspx
MeettheFoodieandtheMD.aspx
OurMenu.aspx

我该怎么做?


1
你不能在数据访问层或表现层完成这个任务吗?比如说在.NET客户端而不是数据库中? - abatishchev
1
你的意思是创建一个程序来完成吗?是的,我可以做到,但有没有在SQL Server中完成它的方法? - Antonio Papa
1
在C#中实现要容易得多,这就是我的意思。但在T-SQL中仍然是可能的。 - abatishchev
我知道,我想我可能会用C#来做,没有人回答 :P - Antonio Papa
16个回答

90

在SQL中完成此操作的方法:

SELECT SUBSTRING( string , LEN(string) -  CHARINDEX('/',REVERSE(string)) + 2  , LEN(string)  ) FROM SAMPLE;

JSFiddle在这里 http://sqlfiddle.com/#!3/41ead/11


1
谢谢,这是正确的答案,因为有些字段没有“/” :) - Antonio Papa
2
也许与上下文中的问题无关,但一般来说,这个解决方案不适用于以下情况:1)只有一个标记(没有分隔符)。在这种情况下,我们期望单个值。2)单个字符标记。 - Mayyit
1
我知道这是一个古老的帖子,但它今天帮了我。我想要删除字符串的最后一个元素,我修改了你的SQL来实现:substring(Name, 1, len(string)-CHARINDEX(' ', reverse(string))) - Jeff Brady

18

1
它给我返回了这个错误:传递给LEFT或SUBSTRING函数的无效长度参数。 - Antonio Papa
+1 很棒的解决方案。就在这个出现之前,我正在输入一条评论,说你可能需要在存储过程/函数循环中使用CHARINDEX。 - PeterJ
@AntonioPapa,请检查您的代码语法,可能有遗漏。请查看SQL Fiddle链接。 - John Woo

8

试试这个。它更容易。

SELECT RIGHT(string, CHARINDEX('/', REVERSE(string)) -1) FROM TableName

1
非常适合 T-SQL,谢谢! - Frank Bailey
如果分隔符字符不在字符串中出现,那么这将无法工作。 - gilad905

8

请尝试以下方法:

select url,(CASE WHEN CHARINDEX('/', url, 1)=0 THEN url ELSE RIGHT(url, CHARINDEX('/', REVERSE(url)) - 1) END)
from(
    select 'Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx' as url union
    select 'OurStory/MeettheFoodieandtheMD.aspx' as url union
    select 'MeettheFoodieandtheMD.aspx' as url
)xx

它按照你的方式工作,但是它给我返回了这个错误: 向 RIGHT 函数传递了无效的长度参数。 - Antonio Papa
我猜添加一个case条件将会消除错误。请检查编辑后的答案。 - TechDo
这正是我想要的。它可以处理没有字符分隔符的元素。 - ch2o
2
这个非常好用。可以处理NULL值,单词(没有分隔符)甚至长度为1或0的字符。 - Mayyit

5
SELECT REVERSE ((
    SELECT TOP 1 value FROM STRING_SPLIT(REVERSE('Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx'), '/')
)) AS fName
Result: Diet.aspx

标准的STRING_SPLIT不允许获取最后一个值。

技巧是在使用STRING_SPLIT之前反转字符串(REVERSE),从末尾获取第一个值(TOP 1 value),然后再次反转结果(REVERSE)以恢复原始字符顺序。

以下是在处理SQL表时常用的方法:

SELECT REVERSE ((
    SELECT TOP 1 VALUE FROM STRING_SPLIT(REVERSE(mySearchString), '/')
)) AS myLastValue
FROM myTable 

string_split函数如果没有序数参数,不能保证顺序。TOP 1如果没有ORDER BY子句是逻辑上的无意义。这种情况下“运行”只是基于运气。 - SMor
请注意,现在某些SQL版本中有带序数的string_split函数。https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15 - Conor Cunningham MSFT

4
一种稍微更加紧凑的做法(类似于ktaria的答案,但适用于SQL Server)是:
SELECT TOP 1 REVERSE(value) FROM STRING_SPLIT(REVERSE(fullPath), '/') AS fileName

3

PostgreSQL的等效功能:

SELECT reverse(split_part(reverse(column_name), '/', 1));

1

你也可以尝试这个

( SELECT TOP(1) value 
    FROM STRING_SPLIT(#string, '/') 
ORDER BY CHARINDEX('/' + value + '/', '/' + #string+ '-') DESC)

使用STRING_SPLIT的想法很有趣 - 即使在实践中,@Tim Grewe的解决方案更简单。 - pygri

1
请尝试以下代码:

SELECT SUBSTRING( attachment, LEN(attachment) 
     - CHARINDEX('/', REVERSE(attachment)) + 2, LEN(attachment)  ) AS filename 
FROM filestable;

1
更简单、优雅的:
select reverse(SPLIT_PART(reverse('Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx'), '/',1))

3
不错,但你的解决方案不是SQL Server :) - H.Scheidl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接