Sql server 在TSQL中颠倒单词的顺序
我想知道如何反转从TSQL字符串varchar返回的单词顺序 我知道TSQL REVERSE函数,但也会反转单词中的字母,例如: 输入>我们想告诉你我们都爱你 输出>wolfrevOkcatS Evolla ew uoy llet ot tnaw ew 我希望在TSQL中实现以下目标: 输入>我们想告诉你我们都爱你 输出>爱你告诉我们想要的一切 我在任何地方发现的唯一一个稍微相似的问题是,这包括拆分逗号分隔的字符串,我不需要这样做 我相信有一种方法可以实现上述功能,即使是自定义函数或SQL-CLR函数,也非常感谢您的帮助 编辑: 我使用以下方法成功地拆分了字符串:Sql server 在TSQL中颠倒单词的顺序,sql-server,sql-server-2005,tsql,sqlclr,Sql Server,Sql Server 2005,Tsql,Sqlclr,我想知道如何反转从TSQL字符串varchar返回的单词顺序 我知道TSQL REVERSE函数,但也会反转单词中的字母,例如: 输入>我们想告诉你我们都爱你 输出>wolfrevOkcatS Evolla ew uoy llet ot tnaw ew 我希望在TSQL中实现以下目标: 输入>我们想告诉你我们都爱你 输出>爱你告诉我们想要的一切 我在任何地方发现的唯一一个稍微相似的问题是,这包括拆分逗号分隔的字符串,我不需要这样做 我相信有一种方法可以实现上述功能,即使是自定义函数或SQL-CL
-- Create a space delimited string for testing
declare @str varchar(max)
select @str = 'We want to tell you we all love StackOverflow'
-- XML tag the string by replacing spaces with </x><x> tags
declare @xml xml
select @xml = cast('<x><![CDATA['+ replace(@str,' ',']]></x><x><![CDATA[') + ']]></x>' as xml)
-- Finally select values from nodes <x> and trim at the same time
select ltrim(rtrim(mynode.value('.[1]', 'nvarchar(50)'))) as Code
from (select @xml doc) xx
cross apply doc.nodes('/x') (mynode)
现在的问题是试图以向后的描述顺序将所有内容重新组合成一个字符串。首先,这是基于CLR的解决方案将变得更好的情况之一,特别是在性能方面,解决方案将始终使用迭代和字符串操作 这里有几行C实现了这个结果,尽管它没有您需要的SQL-CLR代码:
string original = "We want to tell you we all love StackOverflow";
string[] parts = original.Split(' ');
StringBuilder reversedString = new StringBuilder();
for (int i = parts.Length - 1; i >= 0; i--)
{
reversedString.Append(parts[i]);
reversedString.Append(" ");
}
string result = reversedString.ToString();
使用LINQ会更短,但我想我会保持简单。对于T-SQL解决方案,可以从前面提到的vzczc文章中的splitString函数开始
基于此,您可以执行以下操作:
DECLARE @ReverseString VARCHAR(MAX)
SET @ReverseString = ''
SELECT @ReverseString = @ReverseString + s + ' '
FROM
(
SELECT s, zeroBasedOccurance
FROM dbo.SplitString('We want to tell you we all love StackOverflow', ' ')
) A
ORDER BY A.zeroBasedOccurance DESC
SELECT @ReverseString
这应该可以工作,但它用于将字符串重新连接在一起的方法没有文档记录,并且在SQL Server的未来版本中可能无法正常工作。与CLR解决方案相比,它的性能也可能非常差,因此,如果您有时间实现,请这样做。您可以在SQL中创建一个小函数来反转字符串,如下所示:
DECLARE @source VARCHAR(MAX)
DECLARE @dest VARCHAR(MAX)
DECLARE @lenght INT
SET @source = 'We want to tell you we all love StackOverflow'
SET @dest = ''
WHILE LEN(@source) > 0
BEGIN
IF CHARINDEX(' ', @source) > 0
BEGIN
SET @dest = SUBSTRING(@source,0,CHARINDEX(' ', @source)) + ' ' + @dest
SET @source = LTRIM(RTRIM(SUBSTRING(@source,CHARINDEX(' ', @source)+1,LEN(@source))))
END
ELSE
BEGIN
SET @dest = @source + ' ' + @dest
SET @source = ''
END
END
SELECT @dest
SQL Server的本机XML支持允许为这些类型的问题提供一些强大而简洁的解决方案:
DECLARE @xml XML, @source VARCHAR(MAX), @delimiter VARCHAR(10)
SET @source = 'We want to tell you we all love StackOverflow'
SET @delimiter = ' '
SET @xml = CAST(('<X>' + REPLACE(@source, @delimiter, '</X><X>') + '</X>') AS XML)
SELECT STUFF((SELECT @delimiter + C.value('.', 'VARCHAR(50)')
FROM @xml.nodes('X') AS X(C)
ORDER BY ROW_NUMBER() OVER (ORDER BY (SELECT 0)) DESC
FOR XML PATH('')), 1, 1, '')
因为被接受的答案不是一个函数,这里有一个 此外,我还删除了由接受的答案生成的多余无用空间
CREATE FUNCTION [dbo].[fn_ReverseWords] (@input VARCHAR(MAX))
RETURNS VARCHAR(MAX)
BEGIN
DECLARE @output VARCHAR(MAX)
SET @output = ''
WHILE LEN(@input) > 0
BEGIN
IF CHARINDEX(' ', @input) > 0
BEGIN
SET @output = SUBSTRING(@input,0,CHARINDEX(' ', @input)) + ' ' + @output
SET @input = LTRIM(RTRIM(SUBSTRING(@input,CHARINDEX(' ', @input) + 1,LEN(@input))))
END
ELSE
BEGIN
SET @output = @input + ' ' + @output
SET @input = ''
END
END
RETURN substring(@output,0, len(@output)) -- remove useless space
END
我想你可以用你引用的问题,但是用定界符代替逗号。一旦有了拆分列表,就可以很容易地操纵顺序。为什么不使用已经找到的解决方案呢?它用于逗号分隔的字符串,但您的字符串是空格分隔的,因此唯一的区别是分隔符忽略了标点符号问题。更一般地说,这类问题是许多语言中常见的学习或辅导练习,因此,您可以通过尝试自己在TSQL或CLR过程中解决此任务来获得更多信息,然后在遇到特定的编码问题时发布,您可以显示您已经尝试过的代码。检查此问题以了解拆分函数问题的各种解决方案:我没有使用我引用的问题的原因是因为我读过该问题在生产环境中使用游标是个坏主意吗?我相信一定有一个比发布在那里的方式更简单的解决方案?@Aracas:Cursors名声不好,因为大多数人使用它来循环SQL结果集,做一些基于集合的解决方案可以更好地解决的事情。但是我看不出仅仅在几个内存变量上使用游标有什么问题。谢谢John。作为提示,需要在后面添加+1len@output,否则它会截断一封信
CREATE FUNCTION [dbo].[fn_ReverseWords] (@input VARCHAR(MAX))
RETURNS VARCHAR(MAX)
BEGIN
DECLARE @output VARCHAR(MAX)
SET @output = ''
WHILE LEN(@input) > 0
BEGIN
IF CHARINDEX(' ', @input) > 0
BEGIN
SET @output = SUBSTRING(@input,0,CHARINDEX(' ', @input)) + ' ' + @output
SET @input = LTRIM(RTRIM(SUBSTRING(@input,CHARINDEX(' ', @input) + 1,LEN(@input))))
END
ELSE
BEGIN
SET @output = @input + ' ' + @output
SET @input = ''
END
END
RETURN substring(@output,0, len(@output)) -- remove useless space
END