获取从 split_string 中提取的每个字符串的排名
Get the rank of each string extracted from split_string
我有一个 TABLE 和 STR DNA DATA 以下 Table [DYS]
Id
DYS385
3
10-19
4
13-16
5
13-18
6
13-19
7
13-17
8
13-18
9
13-18
10
14-19
11
13-19
12
13-18
我正在使用以下脚本拆分 [DYS385]
的值
select top 10 id,[DYS385],t.Value
from dys
OUTER APPLY(select * from string_split([DYS385],'-')) t
where dys385 is not null
输出
Id
DYS385
VALUE
3
10-19
10
3
10-19
19
4
13-16
13
4
13-16
16
5
13-18
13
5
13-18
18
6
13-19
13
6
13-19
19
7
13-17
13
7
13-17
17
我想为每个值获取排名
例子
10-19 => 10: 排名 1, 19: 排名 2
期望的结果:
Id
DYS385
VALUE
RANK
3
10-19
10
1
3
10-19
19
2
4
13-16
13
1
4
13-16
16
2
5
13-18
13
1
5
13-18
18
2
6
13-19
13
1
6
13-19
19
2
7
13-17
13
1
7
13-17
17
2
Split_string 有一个选项可以输出这个排名,称为序数。只需添加一个值为 1 的额外参数:
SELECT *FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ', 1);
那个returns:
value ordinal
Lorem 1
ipsum 2
dolor 3
sit 4
amet. 5
在您的情况下,查询将是:
select top 10 id,[DYS385],t.* from dys OUTER APPLY(select * from string_split([DYS385],'-',1)) t where dys385 is not null
使用替代 string-split 方法,例如 XML 或 Json 可以 return 一个序数位置,例如:
create function dbo.SplitString(@string varchar(1000), @Delimiter varchar(10))
returns table
as
return(
select j.[value], 1 + Convert(tinyint,j.[key]) Seq
from OpenJson(Concat('["',replace(@string,@delimiter, '","'),'"]')) j
);
select value, Seq as [Rank]
from dbo.SplitString('10-19','-')
order by [Rank];
鉴于此数据:
CREATE TABLE dbo.Something(Id int, DYS385 varchar(10));
INSERT dbo.Something(Id, DYS385) VALUES (3 , '10-19'),
(4 , '13-16'), (5 , '13-18'), (6 , '13-19'),
(7 , '13-17'), (8 , '13-18'), (9 , '13-18'),
(10, '14-19'), (11, '13-19'), (12, '13-18');
确保按正确顺序排列 broken-up 字符串的另一种方法是使用 PARSENAME()
等技巧,尽管这可能对字符串长度以及点是否在其中有效很敏感数据:
SELECT s.Id, s.DYS385, value = v.v, [rank] = ROW_NUMBER() OVER
(PARTITION BY s.Id ORDER BY c.c DESC)
FROM dbo.Something AS s
CROSS APPLY (VALUES(1),(2)) AS c(c)
CROSS APPLY (VALUES(PARSENAME(REPLACE(s.DYS385,'-','.'),c.c))) AS v(v)
ORDER BY s.Id, [rank];
输出:
Id
DYS385
value
rank
3
10-19
10
1
3
10-19
19
2
4
13-16
13
1
4
13-16
16
2
5
13-18
13
1
5
13-18
18
2
6
13-19
13
1
6
13-19
19
2
7
13-17
13
1
7
13-17
17
2
8
13-18
13
1
8
13-18
18
2
9
13-18
13
1
9
13-18
18
2
10
14-19
14
1
10
14-19
19
2
11
13-19
13
1
11
13-19
19
2
12
13-18
13
1
12
13-18
18
2
我们还可以让recursivesplit_string函数returns对每一项的排序如下
Link dbfiddle
Create function Split_Recursive(@string nvarchar(max),@delimiter as varchar(1)) returns Table
as
return(
with cte as(
select 1 N,
case when charindex(@delimiter,@string,1) =0 then @string else
substring(@string,1,-1+charindex(@delimiter,@string,1)) end [Found],
case when charindex(@delimiter,@string,1)=0 then @string else substring(@string,1+charindex(@delimiter,@string,1) ,len(@string))
end [MYSTRING]
union all
select 1+n,
case when charindex(@delimiter,[MYSTRING],1)=0 then [MYSTRING] else
substring([MYSTRING],1,-1+charindex(@delimiter,[MYSTRING],1)) end,substring([MYSTRING],1+charindex(@delimiter,[MYSTRING]),len([MYSTRING])) from cte
where charindex(@delimiter,[MYSTRING],1)>0),
cte2 as (select N,Found from cte
union select 1+t.N,Mystring from cte OUTER APPLY(select top 1 N from cte order by n desc)t where t.n=cte.n
)
select N Rank,Found from cte2
)
go
select * from dbo.Split_Recursive('12-16','-')
输出
Rank
Found
1
12
2
16
我有一个 TABLE 和 STR DNA DATA 以下 Table [DYS]
Id | DYS385 |
---|---|
3 | 10-19 |
4 | 13-16 |
5 | 13-18 |
6 | 13-19 |
7 | 13-17 |
8 | 13-18 |
9 | 13-18 |
10 | 14-19 |
11 | 13-19 |
12 | 13-18 |
我正在使用以下脚本拆分 [DYS385]
的值select top 10 id,[DYS385],t.Value
from dys
OUTER APPLY(select * from string_split([DYS385],'-')) t
where dys385 is not null
输出
Id | DYS385 | VALUE |
---|---|---|
3 | 10-19 | 10 |
3 | 10-19 | 19 |
4 | 13-16 | 13 |
4 | 13-16 | 16 |
5 | 13-18 | 13 |
5 | 13-18 | 18 |
6 | 13-19 | 13 |
6 | 13-19 | 19 |
7 | 13-17 | 13 |
7 | 13-17 | 17 |
我想为每个值获取排名 例子 10-19 => 10: 排名 1, 19: 排名 2
期望的结果:
Id | DYS385 | VALUE | RANK |
---|---|---|---|
3 | 10-19 | 10 | 1 |
3 | 10-19 | 19 | 2 |
4 | 13-16 | 13 | 1 |
4 | 13-16 | 16 | 2 |
5 | 13-18 | 13 | 1 |
5 | 13-18 | 18 | 2 |
6 | 13-19 | 13 | 1 |
6 | 13-19 | 19 | 2 |
7 | 13-17 | 13 | 1 |
7 | 13-17 | 17 | 2 |
Split_string 有一个选项可以输出这个排名,称为序数。只需添加一个值为 1 的额外参数:
SELECT *FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ', 1);
那个returns:
value ordinal
Lorem 1
ipsum 2
dolor 3
sit 4
amet. 5
在您的情况下,查询将是:
select top 10 id,[DYS385],t.* from dys OUTER APPLY(select * from string_split([DYS385],'-',1)) t where dys385 is not null
使用替代 string-split 方法,例如 XML 或 Json 可以 return 一个序数位置,例如:
create function dbo.SplitString(@string varchar(1000), @Delimiter varchar(10))
returns table
as
return(
select j.[value], 1 + Convert(tinyint,j.[key]) Seq
from OpenJson(Concat('["',replace(@string,@delimiter, '","'),'"]')) j
);
select value, Seq as [Rank]
from dbo.SplitString('10-19','-')
order by [Rank];
鉴于此数据:
CREATE TABLE dbo.Something(Id int, DYS385 varchar(10));
INSERT dbo.Something(Id, DYS385) VALUES (3 , '10-19'),
(4 , '13-16'), (5 , '13-18'), (6 , '13-19'),
(7 , '13-17'), (8 , '13-18'), (9 , '13-18'),
(10, '14-19'), (11, '13-19'), (12, '13-18');
确保按正确顺序排列 broken-up 字符串的另一种方法是使用 PARSENAME()
等技巧,尽管这可能对字符串长度以及点是否在其中有效很敏感数据:
SELECT s.Id, s.DYS385, value = v.v, [rank] = ROW_NUMBER() OVER
(PARTITION BY s.Id ORDER BY c.c DESC)
FROM dbo.Something AS s
CROSS APPLY (VALUES(1),(2)) AS c(c)
CROSS APPLY (VALUES(PARSENAME(REPLACE(s.DYS385,'-','.'),c.c))) AS v(v)
ORDER BY s.Id, [rank];
输出:
Id DYS385 value rank 3 10-19 10 1 3 10-19 19 2 4 13-16 13 1 4 13-16 16 2 5 13-18 13 1 5 13-18 18 2 6 13-19 13 1 6 13-19 19 2 7 13-17 13 1 7 13-17 17 2 8 13-18 13 1 8 13-18 18 2 9 13-18 13 1 9 13-18 18 2 10 14-19 14 1 10 14-19 19 2 11 13-19 13 1 11 13-19 19 2 12 13-18 13 1 12 13-18 18 2
我们还可以让recursivesplit_string函数returns对每一项的排序如下 Link dbfiddle
Create function Split_Recursive(@string nvarchar(max),@delimiter as varchar(1)) returns Table
as
return(
with cte as(
select 1 N,
case when charindex(@delimiter,@string,1) =0 then @string else
substring(@string,1,-1+charindex(@delimiter,@string,1)) end [Found],
case when charindex(@delimiter,@string,1)=0 then @string else substring(@string,1+charindex(@delimiter,@string,1) ,len(@string))
end [MYSTRING]
union all
select 1+n,
case when charindex(@delimiter,[MYSTRING],1)=0 then [MYSTRING] else
substring([MYSTRING],1,-1+charindex(@delimiter,[MYSTRING],1)) end,substring([MYSTRING],1+charindex(@delimiter,[MYSTRING]),len([MYSTRING])) from cte
where charindex(@delimiter,[MYSTRING],1)>0),
cte2 as (select N,Found from cte
union select 1+t.N,Mystring from cte OUTER APPLY(select top 1 N from cte order by n desc)t where t.n=cte.n
)
select N Rank,Found from cte2
)
go
select * from dbo.Split_Recursive('12-16','-')
输出
Rank | Found |
---|---|
1 | 12 |
2 | 16 |