长话短说:我试图在我的 STUFF() 函数中使用条件分隔符。出于数据目的,下面示例中的值是基于前两位数字的一系列值。
| uniqueID | value |
| name1 | 110 |
| name1 | 111 |
| name1 | 112 |
| name1 | 113 |
| name1 | 120 |
| name1 | 121 |
| name1 | 130 |
| name1 | 131 |
STUFF() 函数如下所示:
select t.uniqueid, stuff((select distinct ',' + v.value
from #temp v
where v.uniqueID = t.uniqueid
for XML path ('')),1,1,'')
from #temp t
...返回:
| uniqueID | value |
| name1 | 110, 111, 112, 113, 120, 121, 130, 131 |
同样,由于我们在内部根据前两位数字对上述代码进行分类,因此我希望在同一系列内的值之间使用逗号,并在值之间使用唯一的分隔符(例如@)一个系列中的最后一个值和下一个系列中的第一个值。
理想输出:
| uniqueID | value |
| name1 | 110, 111, 112, 113@120, 121@130, 131 |
我的第一个想法是按原样运行 STUFF(),然后在结果字符串中进行搜索,但不确定这是否明智,甚至不确定如何做到这一点。
我的第二个想法是,也许可以使用 CASE WHEN 语句来代替 STUFF() 中的分隔符 ',' 声明,但我同样不知道如何将 STUFF() 中的一个值与下一个值进行比较.
我最后的想法是也许在 STUFF() 之前对值和“系列”结束的位置进行比较,只需添加“+ @”,它会在 STUFF() 期间被拉入。
任何帮助或创造性的方法将不胜感激。提前致谢。
最佳答案
这并不漂亮,但我认为这可行:
-- Set up temp table and test data
create table #values
(
uniqueID varchar(100),
value int
)
insert into #values
select 'name1', 110
union
select 'name1', 111
union
select 'name1', 112
union
select 'name1', 113
union
select 'name1', 120
union
select 'name1', 121
union
select 'name1', 130
union
select 'name1', 131
union
select 'name2', 110
union
select 'name2', 111
union
select 'name2', 112
union
select 'name2', 113
union
select 'name2', 114
union
select 'name2', 120
union
select 'name2', 130
union
select 'name2', 131
union
select 'name2', 132
go
-- Create CTE to add '@' to the last value in each series
with results (uniqueId, [value])
as
(
select distinct
v1.uniqueID
,case when v2.[value] is null then convert(varchar,v1.[value]) + '@' else convert(varchar,v1.[value]) end as [value]
from #values v1
left join #values v2 on v1.uniqueID = v2.uniqueID and v2.[value] > v1.[value] and v1.[value] / 10 = v2.[value] / 10
)
-- Return STUFFed final string (using reverse to remove trailing '@' without repeating code)
select
uniqueId
,reverse(stuff(reverse(replace(stuff((select distinct ',' + [value] from results r2 where r1.uniqueId = r2.uniqueId for xml path ('')),1,1,''),'@,','@')),1,1,'')) as [value]
from results r1
drop table #values
结果:
/-----------------------------------------------\
|uniqueId | value |
|---------|-------------------------------------|
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name1 | 110,111,112,113@120,121@130,131 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
| name2 | 110,111,112,113,114@120@130,131,132 |
\-----------------------------------------------/
关于SQL - STUFF 函数中的 CASE WHEN 作为条件分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45985511/