【问题标题】:Parse a string before the Last Index Of a character in SQL Server在 SQL Server 中一个字符的最后一个索引之前解析一个字符串
【发布时间】:2010-09-16 22:37:09
【问题描述】:

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

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 中执行此任务的有效方法?

请注意,我所拥有的东西是有效的,我只是想知道这是否是最好的方法。

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

【问题讨论】:

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


    【解决方案1】:

    我可以建议您简化一下您的表达方式:

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

    此外,据我所知,当您需要字符串的其余部分时,使用 substring 函数指定 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 SELECTs 应该是UNION ALL SELECT,因为没有ALL,引擎必须删除重复项,就像您指出SELECT DISTINCT 一样。只需养成使用ALL 的习惯,您就会过得更好。 :)

    【讨论】:

      【解决方案2】:

      不确定#1,但我会说您最好在代码中执行此操作。您是否有理由必须在数据库中执行此操作?

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

      【讨论】:

      • 它是在 SQL 中完成的,因为这确实是唯一的选择,因为黑客和某人很懒(不是我)。有人问我是否有办法为他们获取值,所以我将其提供给他们并提醒他们注意它的用途。我一直想知道当它们在相同字段上时在选择中使用替换或反转等功能以及它是如何工作的。我认为这是一个很好的示例问题,我遇到了这个问题。我同意最好的方法是在客户端代码中以某种方式进行。
      • 顺便说一句 - 忘了提到我没有遇到性能问题,但我经常编写对数千行进行操作的查询,并使用字符串函数来填充报告表,并且很好奇事情是如何工作的。如您所知,我能做的任何事情来优化查询性能总是一个加分项。
      【解决方案3】:

      我也不确定 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
      

      我很好奇这些更改中的任何一个都会产生多大的不同。

      【讨论】:

        【解决方案4】:
        1. 3 个内部反向是彼此离散的。外部反转将反转已被内部反转的任何内容。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-05-06
          • 1970-01-01
          • 2011-08-13
          • 2013-05-30
          • 1970-01-01
          • 1970-01-01
          • 2016-04-25
          相关资源
          最近更新 更多