Tsql 在SQL Server 2008中,从字符串中获取下划线之前的字符,并用逗号分隔
我试过这个问题Tsql 在SQL Server 2008中,从字符串中获取下划线之前的字符,并用逗号分隔,tsql,sql-server-2008,Tsql,Sql Server 2008,我试过这个问题 DECLARE @AdvancedSearchSelectedDropdownName TABLE ( SelectedIds VARCHAR(2048), AdvanceSearchOptionTypeId INT ) INSERT INTO @AdvancedSearchSelectedDropdownName VALUES ('4_0,5_1,6_2,7_3', 23), ('62_3', 21), ('2_4', 23) DECLARE
DECLARE @AdvancedSearchSelectedDropdownName TABLE (
SelectedIds VARCHAR(2048),
AdvanceSearchOptionTypeId INT
)
INSERT INTO @AdvancedSearchSelectedDropdownName
VALUES ('4_0,5_1,6_2,7_3', 23),
('62_3', 21), ('2_4', 23)
DECLARE @selectedIds VARCHAR(MAX) = '';
SELECT @selectedIds +=
CASE WHEN SelectedIds IS NULL
THEN @selectedIds + ISNULL(SelectedIds + ',', '')
WHEN SelectedIds IS NOT NULL
THEN SUBSTRING(SelectedIds, 0, CHARINDEX('_', SelectedIds, 0)) + ','
END
FROM @AdvancedSearchSelectedDropdownName WHERE advanceSearchOptionTypeId = 23
SELECT @selectedIds
电流输出:4,2
所需输出:4,5,6,7,2
在SelectedDS列中,可能有n个逗号分隔的值。您可以这样做:
WITH Casted AS
(
SELECT *
,CAST('<x><y>' + REPLACE(REPLACE(SelectedIds,'_','</y><y>'),',','</y></x><x><y>') + '</y></x>' AS XML) SplittedToXml
FROM @AdvancedSearchSelectedDropdownName
)
SELECT *
FROM Casted;
提示:不要存储逗号分隔的值!
以这种格式存储数据是一个非常糟糕的主意。您可以使用诸如my XML之类的通用格式来存储此文件或相关副表的结构。但这样的构造往往会成为一个真正的麻烦…免责声明。根据第一个标准形式,您不应该在单个单元格中存储多个值。我建议您避免以这种方式存储。
方法仍然是:创建一个UDF函数,将逗号分隔的列表分隔为表值变量。下面的代码我还没有测试过。但是,它给出了如何处理这个问题的想法
如果对助手函数感兴趣 厌倦了提取字符串左,右,charindex,patindex。。。我修改了s split/parse函数以接受两个不相似的分隔符。在这种情况下,a和 范例 返回 TVF如果感兴趣
再想想。也许更简单一点 现在,如果你有有限的 范例 返回
阅读,你会看到很多原因,为什么这个问题的答案绝对是肯定的!繁重的工作是标记器。。。顺便说一句,这个选择@selectedIds+=。。。称为古怪更新,不建议连接字符串。可能会有意想不到的结果。。。更好地使用XML路径,从v2016开始,有一个字符串\u AGG…在其中挖掘嵌套的XMLpass@JohnCappelletti是的,很酷。我曾经在分解多行csv时发现了这个。在一次传递中使用换行符和分号,并将整个文件作为xml获取。
<x>
<y>4</y>
<y>0</y>
</x>
<x>
<y>5</y>
<y>1</y>
</x>
<x>
<y>6</y>
<y>2</y>
</x>
<x>
<y>7</y>
<y>3</y>
</x>
WITH Casted AS
(
SELECT *
,CAST('<x><y>' + REPLACE(REPLACE(SelectedIds,'_','</y><y>'),',','</y></x><x><y>') + '</y></x>' AS XML) SplittedToXml
FROM @AdvancedSearchSelectedDropdownName
)
SELECT Casted.AdvanceSearchOptionTypeId AS TypeId
,x.value('y[1]/text()[1]','int') AS IdValue
FROM Casted
CROSS APPLY SplittedToXml.nodes('/x') A(x);
TypeId IdValue
23 4
23 5
23 6
23 7
21 62
23 2
Declare @selectedIds varchar(max) = '';
SET @selectedIds = SELECT STUFF
(SELECT ','+ (SUBSTRING(c.value, 0, CHARINDEX('_', c.value, 0))
FROM @AdvancedSearchSelectedDropdownName AS tv
CROSS APPLY dbo.udfForCSVToList(SelectedIds) AS c
WHERE advanceSearchOptionTypeId = 23
FOR XML PATH('')),1,2,'');
SELECT @selectedIds
;with cte as (
Select A.AdvanceSearchOptionTypeId
,B.*
,RN = Row_Number() over(Order by (Select NULL))
From @AdvancedSearchSelectedDropdownName A
Cross Apply [dbo].[tvf-Str-Extract](','+A.SelectedIds,',','_') B
)
Select AdvanceSearchOptionTypeId
,IDs = stuff((Select ',' +RetVal From cte Where AdvanceSearchOptionTypeId=A.AdvanceSearchOptionTypeId Order by RN,RetVal For XML Path ('')),1,1,'')
From cte A
Group By AdvanceSearchOptionTypeId
AdvanceSearchOptionTypeId IDs
21 62
23 4,5,6,7,2
CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By N)
,RetPos = N
,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1)
From (
Select *,RetVal = Substring(@String, N, L)
From cte4
) A
Where charindex(@Delimiter2,RetVal)>1
)
/*
Max Length of String 1MM characters
Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (@String,'[[',']]')
*/
;with cte as (
Select *
,RN = Row_Number() over(Order by (Select NULL))
From @AdvancedSearchSelectedDropdownName A
)
Select AdvanceSearchOptionTypeId
,IDs = replace(
replace(
replace(
replace(
replace(
stuff((Select ',' +SelectedIds From cte Where AdvanceSearchOptionTypeId=A.AdvanceSearchOptionTypeId Order by RN For XML Path ('')),1,1,'')
,'_0','')
,'_1','')
,'_2','')
,'_3','')
,'_4','')
From cte A
Group By AdvanceSearchOptionTypeId
AdvanceSearchOptionTypeId IDs
21 62
23 4,5,6,7,2