【问题标题】:SQL Server 2005 - RIGHT() not working when adding to CHARINDEX()SQL Server 2005 - 添加到 CHARINDEX() 时 RIGHT() 不起作用
【发布时间】:2015-05-28 13:46:55
【问题描述】:

我正在尝试使用RIGHT 函数来获取包含“/”的值的子字符串,但是当我将数字添加到CHARINDEX 值时它不起作用;只有没有。

下面是代码示例:

SELECT CASE
            WHEN 
                CHARINDEX('/',REPLACE(ISNULL(d.target_grade,'NA'), 'N/A', 'NA')) = 0
            THEN 
                REPLACE(ISNULL(d.target_grade,'NA'),'N/A','NA')
            ELSE 
                RIGHT(d.target_grade, CHARINDEX('/',REPLACE(ISNULL(d.target_grade,'NA'), 'N/A', 'NA'))+1)
        END as target_grade
FROM tbl --etc.

这会返回例如

target_grade
-------------
C/D

它应该通过这个返回

target_grade
-------------
D

但是,如果我删除 +1RIGHT 函数将完全正常工作

target_grade
-------------
/D

我在这里做错了什么?我的逻辑有问题吗?

【问题讨论】:

  • 你的逻辑是错误的 - charindex 从字符串的 left 开始计数,但 right 从字符串的 right 开始计数。 ..
  • 所有答案都正确,选择@PhilipKelley 指出额外的注意事项。

标签: sql-server-2005 charindex


【解决方案1】:

我建议通过利用CASE 语句的强大功能来避免过于复杂的字符串操作。试试这样的:

CASE
  when d.target_grade is null then 'NA'
  when d.target_grade = 'N/A' then 'NA'
  when charindex('/', d.target_grade) = 0 then d.target_grade
  else substring(d.target_grade, charindex('/', d.target_grade) + 1, XX)  --  Replace XX with the max posssible length of d.target_grade
END

【讨论】:

    【解决方案2】:

    由于RIGHT 想要“保留多少个字符”而不是“从哪里开始字符串”,所以您当前的逻辑是错误的。

    更简单,如果你已经有了“从哪里开始字符串”是使用SUBSTRING

    SELECT CASE
                WHEN 
                    CHARINDEX('/',REPLACE(ISNULL(d.target_grade,'NA'), 'N/A', 'NA')) = 0
                THEN 
                    REPLACE(ISNULL(d.target_grade,'NA'),'N/A','NA')
                ELSE 
                    SUBSTRING(d.target_grade, 
                             CHARINDEX('/',REPLACE(ISNULL(d.target_grade,'NA'), 'N/A', 'NA'))+1
                              ,8000)
            END as target_grade
    FROM tbl
    

    【讨论】:

      【解决方案3】:

      愚蠢的我,就像@MarkBannister 说的那样,charindex 从字符串的左侧开始计数,但right 从字符串的右侧开始计数。因此以上应该是

      SELECT CASE
                  WHEN 
                      CHARINDEX('/',REPLACE(ISNULL(d.target_grade,'NA'), 'N/A', 'NA')) = 0
                  THEN 
                      REPLACE(ISNULL(d.target_grade,'NA'),'N/A','NA')
                  ELSE
                      -- Use -1 NOT 1 
                      RIGHT(d.target_grade, CHARINDEX('/',REPLACE(ISNULL(d.target_grade,'NA'), 'N/A', 'NA'))-1)
              END as target_grade
      FROM tbl --etc.
      

      -1不是+1

      【讨论】:

      • 只有当你碰巧知道斜线正好出现在字符串的中心时,这才是正确的。如果您期望ABC/D 返回D(您的版本将返回C/D),则此逻辑仍然不正确。如果您坚持使用RIGHT 而不是SUBSTRING,正确的做法是从LEN 中减去CHARINDEX 结果。
      • @Damien_The_Unbeliever 啊,我明白了,感谢您指出这一点。
      猜你喜欢
      • 2011-02-21
      • 2018-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多