Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 从表中的字符串中获取最后一个单词_Sql Server - Fatal编程技术网

Sql server 从表中的字符串中获取最后一个单词

Sql server 从表中的字符串中获取最后一个单词,sql-server,Sql Server,我正试图从SQL Server 2017中的表Project中获取最后一个单词 我的代码如下: select reverse(substring(reverse(ProjectDescription),1, charindex(' ', reverse(ProjectDescription)) -1)) as LastWord from Project 如果我要求将表分隔为一行,代码会起作用,但我需要字段ProjectDescription中所有行的最后一个字 当我像上面那样运行代码时,我

我正试图从SQL Server 2017中的表
Project
中获取最后一个单词

我的代码如下:

select 
reverse(substring(reverse(ProjectDescription),1, charindex(' ', reverse(ProjectDescription)) -1)) as LastWord
from Project 
如果我要求将表分隔为一行,代码会起作用,但我需要字段
ProjectDescription
中所有行的最后一个字

当我像上面那样运行代码时,我得到以下错误:

传递给LEFT或SUBSTRING函数的长度参数无效


请有人帮我找出哪里出了问题

我使用表值函数的组合将列表拆分为有序列表。然后使用rownumber只取最后一个

这里有一个函数。外面有很多这样的东西

create FUNCTION SplitString
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (
       ct int
      ,Item NVARCHAR(1000)
)
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT,@ct int =0

      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)
            set @ct=@ct+1

            INSERT INTO @Output(Ct,Item)
            SELECT @ct,SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
GO
下面是提取最后一个单词的SQL:

select *
from (
        select * ,rn = ROW_NUMBER() over (partition by sentence order by ct desc)
        from @t t
            cross apply dbo.splitstring(t.sentence,' ')
    ) a
where rn=1
结果:

sentence                            ct  Item    rn
The brown dog jumped over the fence 7   fence   1
This is the final word              5   word    1

迟交答案,仅作为指导发布。

没有必要拆分字符串。您的错误仅仅是因为charindex()返回了零。简单的修复方法是在charindex()中添加一个“故障保护”,方法是在字符串中添加一个空格,从而确保命中率

此外,请注意肖恩的建议。几年前,我有一个类似的拆分函数,并且对性能的提高感到惊讶

示例

Declare @YourTable Table ([ID] varchar(50),[ProjectDescription] varchar(50))  Insert Into @YourTable Values 
 (1,'Some Project Item or Description') -- Multiword strubg
,(2,'OneWord    ')                      -- One word with trailing blanks
,(3,NULL)                               -- A NULL value
,(4,'')                                 -- An Empty String

Select * 
      ,LastWord = right(rtrim([ProjectDescription]),charindex(' ',reverse(rtrim([ProjectDescription]))+' ')-1)
 From  @YourTable 
返回

ID  ProjectDescription                  LastWord
1   Some Project Item or Description    Description
2   OneWord                             OneWord
3   NULL                                NULL
4       

您可以使用以下简单功能:

create function dbo.getLastWord(@s varchar(100))
returns varchar(200)
as
begin
declare @i int
set @i=len(@s)
 while substring(@s,@i,1)<>' '
  set @i=@i-1
 return substring(@s,@i,len(@s)-@i+1)
end
其中包括:

better

在提取子字符串之前,您可能需要检查字符串的长度,例如,它可能没有空格,因此
charindex
的第二个参数可能为零。使用
case/when
函数检查是否存在空格。谢谢Peter!这仅仅是一行有一个单词引起的问题。这个函数效率非常低。多语句表值函数甚至比标量函数慢。有比使用循环更好的分割字符串的方法。或者任何一个,甚至是内置的,我同意我抓到了一个基本的。功能并不是问题的一部分。我的首选是xml,因为我仍然使用SQL2012@KeithL这里有一个旧版本,也是闪电般的快。是的,我知道这不是问题的一部分,但它是你解决方案的一个组成部分。我看不到那种拆分器被张贴出来,却不说些什么。:)我不是有意改变这个决定的吗
select dbo.getLastWord('Feels things getting better')
better