在 SQL Server 中解析字符的最后一个索引之前的字符串
我从这个开始,但这是执行任务的最佳方式吗?
select
reverse(
substring(reverse(some_field),
charindex('-', reverse(some_field)) + 1,
len(some_field) - charindex('-', reverse(some_field))))
from SomeTable
- SQL Server 如何处理 多次调用
反向(some_field)
? - 除了 UDF 和迭代之外 寻找
charindex
的字符串 '-' 并存储最后一个 索引,还有吗 在 T-SQL 中执行此任务的有效方法是什么?
请注意,我所拥有的有效,我只是想知道这是否是最好的方法。
以下是 some_field 的一些示例值。
s2-st, s1-st, s3-st, s3-sss-zzz, s4-sss-zzzz
编辑:
此示例输出将是...
s1, s2, s3-sss, s3, s4-sss
ErikE 编写的解决方案实际上是获取字符串的结尾,因此最后一个连字符之后的所有内容。我只是修改了他的版本以获取之前的所有内容,而不是使用带有 left
函数的类似方法。感谢您的帮助。
select left(some_field, abs(charindex('-', reverse(some_field)) - len(some_field)))
from (select 's2-st' as some_field
union select 's1-st'
union select 's3-st'
union select 's3-sss-zzz'
union select 's4-sss-zzzz') as SomeTable
I started with this but is it the best way to perform the task?
select
reverse(
substring(reverse(some_field),
charindex('-', reverse(some_field)) + 1,
len(some_field) - charindex('-', reverse(some_field))))
from SomeTable
- How does SQL Server treat the
multiple calls toreverse(some_field)
? - Besides a UDF and iterating through
the string looking forcharindex
of the '-' and storing the last
index of it, is there a more
efficient way to perform this task in T-SQL?
Note that what I have works, I just am really wondering if it is the best way about it.
Below are some sample values for some_field.
s2-st, s1-st, s3-st, s3-sss-zzz, s4-sss-zzzz
EDIT:
Sample output for this would be...
s1, s2, s3-sss, s3, s4-sss
The solution ErikE wrote is actually getting the end of the string so everything after the last hyphen. I just modified his version to get everything before it instead using a similar method with the left
function. Thanks for all of your your help.
select left(some_field, abs(charindex('-', reverse(some_field)) - len(some_field)))
from (select 's2-st' as some_field
union select 's1-st'
union select 's3-st'
union select 's3-sss-zzz'
union select 's4-sss-zzzz') as SomeTable
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我可以建议您简化表达式吗:
此外,据我所知,当您需要字符串的其余部分时,使用 substring 函数指定 8000 个字符的长度并没有什么坏处。只要它不是 varchar(max),它就可以正常工作。
如果这是您必须一直重复执行的操作,那么#1 将数据拆分为单独的列并以这种方式存储,或者 #2 添加带有索引的计算列,这将执行在更新/插入时计算一次,以后不再计算。
最后,我不知道SQL Server是否足够聪明,可以仅反转(some_field)一次并将其注入到另一个实例中。当我有时间时,我会尝试弄清楚。
更新
哎呀,不知怎的,我得到了你想要的东西。对此感到抱歉。您显示的新表达式仍然可以稍微简化:
表达式中的 abs() 只是反转符号。所以我用
+ len - charindex
而不是+ charindex - len
现在一切都很好。它甚至适用于没有破折号的字符串。还要提一下:您的
UNION SELECT
应该是UNION ALL SELECT
因为如果没有ALL
,引擎必须删除重复项,就像您已指定SELECT DISTINCT
。只需养成使用ALL
的习惯,您的情况就会好得多。 :)May I suggest this simplification of your expression:
Also, there's no harm, as far as I know, in specifying 8000 characters in length with the substring function when you want the rest of the string. As long as it's not varchar(max), it works just fine.
If this is something you have to do all the time, over and over, how about #1 splitting out the data into separate columns and storing it that way, or #2 adding a calculated column with an index on it, which will perform the calculation once at update/insert time and not again later.
Last, I don't know if SQL Server is smart enough to reverse(some_field) only once and inject it into the other instance. When I get some time I'll try to figure it out.
Update
Oops, somehow I got backwards what you wanted. Sorry about that. The new expression you showed can still be simplified a little:
The abs() in your expression was just reversing the sign. So I put
+ len - charindex
instead of+ charindex - len
and all is well now. It even works for strings without dashes.One more thing to mention: your
UNION SELECT
s should beUNION ALL SELECT
because without theALL
, the engine has to remove duplicates just as if you'd indicatedSELECT DISTINCT
. Simply get in the habit of usingALL
and you'll be much better off. :)不确定#1,但我想说你最好在代码中这样做。有什么理由必须在数据库中执行此操作吗?
您是否因为某些类似的代码而遇到性能问题,或者这纯粹是假设的。
Not sure about #1, but I would say that you might be better off doing this in code. Is there a reason you have to do it in the database?
Are you experiencing performance problems because of some similar code or is this purely hypothetical.
我也不确定 SQL Server 如何处理对 REVERSE 和 CHARINDEX 的多次调用。
您可以消除对 CHARINDEX 的最后一次调用,因为您希望将所有内容都带到字符串的末尾:
尽管我建议不要这样做,但您也可以用列的大小替换 LEN 函数调用:
我很好奇有多少这些改变中的任何一个都会产生差异。
I am also not sure how SQL Server handles the multiple calls to REVERSE and CHARINDEX.
You can eliminate the last call to CHARINDEX since you want to take everything to the end of the string:
Although I would recommend against it, you could also replace the LEN function call with the size of the column:
I am curious how much of a difference either of these changes would make.
3 个内部反转彼此独立。外部反转将反转任何已被内部反转反转的内容。
ErikE 的方法最适合作为纯 TSQL 解决方案。您不需要 LEN
The 3 inner reverses are discrete from each other. The outer reverse will reverse anything that is already reversed by the inner ones.
ErikE's approach is best as a pure TSQL solution. You don't need LEN