例如:
需要对上面的内容进行排序,
发布于 2018-01-05 12:26:29
所以你不能在本土做任何事情。如果希望将值排序为返回值,即不更新数据库本身,则可以使用存储过程或视图来转换结果。
所以,让我们构建一个答案。
让我们假设您想要在视觉上做到这一点,只为一行。如果您有SQL 2016,您可以使用裂开,但SQL不使用,所以我使用了一个通用的UDF fnSplitString
http://sqlfiddle.com/#!6/7194d/2
SELECT value FROM fnSplitString('Pillars 101 in an apartment', ' ') WHERE RTRIM(value) <> '';
给了我每一个词,分开。点菜怎么样?
SELECT value FROM fnSplitString('Pillars 101 in an apartment', ' ') WHERE RTRIM(value) <> '' ORDER BY value;
如果我想对DB表中的每一行执行此操作?http://sqlfiddle.com/#!6/7194d/8
SELECT split.value FROM [Data] d CROSS APPLY dbo.fnSplitString(IsNull(d.Value,''), ' ') AS split WHERE RTRIM(split.value) <> '' ORDER BY value;
这有点帮助,不过现在我的话都乱七八糟了。让我们回到原来的查询,并标识每一行。每一行可能都有一个标识列。如果是这样的话,你就有你的分组了。如果没有,可以使用ROW_NUMBER,例如:
SELECT ROW_NUMBER() OVER(ORDER BY d.Value) AS [Identity] -- here, use identity instead of row_number , d.Value FROM [Data] d
如果我们在select中使用这个查询作为子查询,我们会得到:
http://sqlfiddle.com/#!6/7194d/21
SELECT d.[Identity], split.value FROM ( SELECT ROW_NUMBER() OVER(ORDER BY d.Value) AS [Identity] -- here, use identity instead of row_number , d.Value FROM [Data] d ) d CROSS APPLY dbo.fnSplitString(IsNull(d.Value,''), ' ') AS split WHERE RTRIM(split.value) <> '' ORDER BY d.[Identity], value;
该查询现在对每个标识中的所有行进行排序。但是现在你需要把这些单词重新组合成一个字符串,对吗?为此,您可以使用料子。在我的例子中,我使用了一个由于SQL的限制,CTE,但是您也可以使用一个临时表。
WITH tempData AS ( SELECT d.[Identity], split.value FROM ( SELECT ROW_NUMBER() OVER(ORDER BY d.Value) AS [Identity] -- here, use identity instead of row_number , d.Value FROM [Data] d ) d CROSS APPLY dbo.fnSplitString(IsNull(d.Value,''), ' ') AS split WHERE RTRIM(split.value) <> '' ) SELECT grp.[Identity] , STUFF((SELECT N' ' + [Value] FROM tempData WHERE [Identity] = grp.[Identity] ORDER BY Value FOR XML PATH(N'')) , 1, 1, N'') FROM (SELECT DISTINCT [Identity] FROM tempData) AS grp
以下是最终结果:http://sqlfiddle.com/#!6/7194d/27
正如在注释中已经表达的那样,--这不是SQL的常见情况。这对服务器来说是不必要的负担。我建议从SQL中提取数据,并通过所选择的编程语言对其进行排序;或者在将数据插入到DB中时确保对其进行排序。我做这个练习是因为我有几分钟的时间:)
发布于 2018-01-05 12:33:34
试试这个:
DECLARE @tbl TABLE(YourString VARCHAR(100));
INSERT INTO @tbl VALUES
('Pillars 101 in an apartment')
,('Zuzu Durga International Hotel')
,('Wyndham Garden Fresh Meadows');
SELECT CAST('<x>' + REPLACE((SELECT YourString AS [*] FOR XML PATH('')),' ','</x><x>') + '</x>' AS XML).query
('
for $x in /x
order by $x
return
concat($x/text()[1], " ")
').value('.','varchar(max)')
FROM @tbl; 代码将首先以像<x>Pillars</x><x>101</x> ...这样的XML格式传输文本。
然后使用FLWOR XQuery返回排序的文本部分。
对.value()的最后一次调用将再次将排序的片段作为文本返回。
结果
101 Pillars an apartment in
Durga Hotel International Zuzu
Fresh Garden Meadows Wyndham 最后陈述
这个代码是一种练习。你的设计很糟糕,应该改变一下.
发布于 2018-01-05 14:10:04
在Shnugo的解决方案上已经+1了。我真的在看他的帖子。
只是另一个选项,使用解析UDF与交叉应用协同使用。
示例
Select B.*
From YourTable A
Cross Apply ( Select Sorted=Stuff((Select ' ' +RetVal From [dbo].[tvf-Str-Parse](A.SomeCol,' ') Order By RetVal For XML Path ('')),1,1,'') )B返回
Sorted
101 an apartment in Pillars
Durga Hotel International Zuzu
Fresh Garden Meadows Wyndham(如果有兴趣的话) UDF
CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
--Thanks Shnugo for making this XML safe
--Select * from [dbo].[tvf-Str-Parse]('Dog,Cat,House,Car',',')https://stackoverflow.com/questions/48112134
复制相似问题