在SQL Server中的字符的最后索引之前解析字符串

时间:2010-09-16 22:37:10

标签: sql sql-server tsql sql-server-2000

我从这开始,但它是执行任务的最佳方式吗?

select  
    reverse(
        substring(reverse(some_field),
        charindex('-', reverse(some_field)) + 1, 
        len(some_field) - charindex('-', reverse(some_field)))) 
from SomeTable
  1. SQL Server如何处理 多次通话 reverse(some_field)
  2. 除了UDF和迭代之外 寻找charindex的字符串 ' - '并存储最后一个 它的索引,还有更多 在T-SQL中执行此任务的有效方法?
  3. 请注意我的作品,我真的很想知道它是否是最佳方式。

    以下是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
    

4 个答案:

答案 0 :(得分:5)

我可以建议你简化你的表达方式:

select right(some_field, charindex('-', reverse(some_field)) - 1)
from SomeTable

另外,据我所知,当你需要字符串的其余部分时,使用子字符串函数指定长度为8000个字符是没有害处的。只要它不是varchar(max),它就可以正常工作。

如果这是你必须一直做的事情,一遍又一遍,#1如何将数据拆分成单独的列并以这种方式存储,或者#2添加一个带有索引的计算列,将在更新/插入时执行一次计算,而不是稍后再执行。

最后,我不知道SQL Server是否足够聪明,只能反转(some_field)一次并将其注入另一个实例。当我有时间的时候,我会试着想出来。

<强>更新

哎呀,不知怎的,我倒退了你想要的东西。对于那个很抱歉。您展示的新表达式仍然可以简化一点:

select left(some_field, len(some_field) - charindex('-', reverse(some_field)))
from (
   select 's2-st'
   union all select 's1-st'
   union all select 's3-st'
   union all select 's3-sss-zzz'
   union all select 's4-sss-zzzz'
   union all select 's5'
) X (some_field)

表达式中的abs()只是反转符号。所以我把+ len - charindex代替+ charindex - len,现在一切都很好。它甚至适用于没有破折号的字符串。

还有一件事需要提及:您的UNION SELECT应为UNION ALL SELECT,因为如果没有ALL,引擎必须删除重复项,就像您指示SELECT DISTINCT一样。只要养成使用ALL的习惯,你就会好多了。 :)

答案 1 :(得分:0)

不确定#1,但我会说你在代码中做得更好。您是否有必要在数据库中执行此操作?

您是否因为某些类似的代码而遇到性能问题,或者这是纯粹的假设。

答案 2 :(得分:0)

我也不确定SQL Server如何处理对REVERSE和CHARINDEX的多次调用。

您可以取消对CHARINDEX的最后一次调用,因为您想将所有内容都带到字符串的末尾:

select  
    reverse(
        substring(reverse(some_field),
        charindex('-', reverse(some_field)) + 1, 
        len(some_field))) 
from SomeTable

虽然我建议反对它,你也可以用列的大小替换LEN函数调用:

select  
    reverse(
        substring(reverse(some_field),
        charindex('-', reverse(some_field)) + 1, 
        1024)) 
from SomeTable

我很好奇这些变化会带来多大的不同。

答案 3 :(得分:0)

  1. 3个内部反转彼此分离。外部反向将反转已被内部反转的任何内容。

  2. ErikE的方法最适合作为纯粹的TSQL解决方案。你不需要LEN