反转 T-SQL 中的单词顺序

发布于 2024-12-08 15:32:17 字数 1225 浏览 0 评论 0 原文

我想知道如何(如果可能)反转从 T-SQL 字符串(varchar)返回的单词的顺序。

我了解 T-SQL REVERSE 函数。但该函数还会反转单词中的字母,例如:

输入> 我们想告诉您,我们都喜欢 StackOverflow
输出> wolfrevOkcatS evol lla ew uoy llet ot tnaw eW

我想在 T-SQL 中实际实现以下

目标 : 我们想告诉您,我们都喜欢 StackOverflow
输出> Stackoverflow 喜欢你告诉我们想要的一切

我在任何地方发现的唯一稍微相似的问题是 这个,但是这包括分割逗号分隔的字符串,这是我不需要做的。

我确信有一种方法可以实现上述目标,即使它是自定义函数或 SQL-CLR 函数。


我设法使用以下方法将字符串拆分:

-- 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)

现在的问题是尝试按向后(DESC)顺序将其全部重新组合成一个字符串。

I would like to know how (if it is possible) to reverse the order of words returned from a T-SQL string (varchar).

I know about the T-SQL REVERSE function. but the function also reverses the letters in the word for example:

Input > We want to tell you we all love StackOverflow
Output > wolfrevOkcatS evol lla ew uoy llet ot tnaw eW

I want to actually achieve the following in T-SQL:

Input > We want to tell you we all love StackOverflow
Output > Stackoverflow love all we you tell to want We

The only slightly similar question I found anywhere was this one, however that includes splitting comma-separated strings which I do not need to do.

I'm sure there is a way to achieve the above, even if it's a custom function or SQL-CLR function.


I managed to split my string up using the following:

-- 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)

The problem now is trying to piece it all back together into one string in a backwards (DESC) order.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

阪姬 2024-12-15 15:32:18

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, '')

SQL Server’s native XML support allows for some powerful (and concise) solutions to these sorts of problems:

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, '')
執念 2024-12-15 15:32:18

由于接受的答案不是函数,因此这里是一个函数。

我还删除了由接受的答案生成的额外无用空间

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

Since the accepted answer is not a function, here is one.

Also I removed the extra useless space generated by the accepted answer

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
命比纸薄 2024-12-15 15:32:17

您可以在 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

You can create one small function in SQL to reverse a string like below:

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
勿忘初心 2024-12-15 15:32:17

首先,这是基于 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 解决方案相比,它的性能也可能非常差,因此,如果您有时间来实现它,请这样做。

Firstly, this is one of those cases where a CLR-based solution is going to be better, especially in terms of performance (the solution will invariable make use of iterations and string manipulation).

Here's a few lines of C# that achieves the result, although it has none of the SQL-CLR code you will need:

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();

It would be even shorter with LINQ, but I thought I'd keep it simple. For a T-SQL solution, you can start with the splitString function in vzczc's post in the split post already mentioned.

Based on that, you do this:

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

This should work, but the method it uses for concatenating the string back together is undocumented and may not work correctly in future versions of SQL Server. It will probably also perform very badly when compared to a CLR solution, so if you have the time to implement that, do so.

离笑几人歌 2024-12-15 15:32:17
declare @str varchar(100),
        @result varchar(100)

set @str = 'We want to tell you we all love StackOverflow'

;with cte as 
(
select 1 pos_from, charindex(' ', @str) + 1 pos_to
union all
select pos_to, charindex(' ', @str + ' ', pos_to) + 1
from cte
where pos_to <= len(@str)
)
select @result = coalesce( @result + ' ', '') +substring(@str, pos_from, pos_to - pos_from - 1) 
from cte
order by pos_to desc

select @result
declare @str varchar(100),
        @result varchar(100)

set @str = 'We want to tell you we all love StackOverflow'

;with cte as 
(
select 1 pos_from, charindex(' ', @str) + 1 pos_to
union all
select pos_to, charindex(' ', @str + ' ', pos_to) + 1
from cte
where pos_to <= len(@str)
)
select @result = coalesce( @result + ' ', '') +substring(@str, pos_from, pos_to - pos_from - 1) 
from cte
order by pos_to desc

select @result
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文