【问题标题】:separate the string by delimiter and assign to variable - sql通过分隔符分隔字符串并分配给变量 - sql
【发布时间】:2018-04-13 05:53:09
【问题描述】:

我有字符串'sunday,monday,thursday' 我想将它们分开并将它们分配给像@day1, @day2, @day3 这样的变量。有时刺痛的天数会有所不同。如何在sql中实现这一点?

【问题讨论】:

  • Sql-server 版本是什么?
  • sql server 2016
  • 使用String_Split函数将字符串用逗号分割,并将每个值赋给变量。

标签: sql sql-server delimiter


【解决方案1】:

试试下面的

DECLARE
  @day1 varchar(10),
  @day2 varchar(10),
  @day3 varchar(10),
  @day4 varchar(10)

DECLARE @Split TABLE (N int IDENTITY, S varchar(200))

INSERT @Split (S) SELECT value FROM STRING_SPLIT('sunday,monday,thursday',',')

SELECT
  @day1=MAX(CASE WHEN N=1 THEN S END),
  @day2=MAX(CASE WHEN N=2 THEN S END),
  @day3=MAX(CASE WHEN N=3 THEN S END),
  @day4=MAX(CASE WHEN N=4 THEN S END) -- is null
FROM @Split

-- check
SELECT @day1,@day2,@day3,@day4

具有 CTE 的变体

DECLARE
  @day1 varchar(10),
  @day2 varchar(10),
  @day3 varchar(10),
  @day4 varchar(10),
  @day5 varchar(10),
  @day6 varchar(10),
  @day7 varchar(10)

DECLARE @input varchar(100)='sunday,monday,thursday'

;WITH sCTE AS(
  SELECT
    1 n,
    NULLIF(LEFT(@input,ISNULL(NULLIF(CHARINDEX(',',@input)-1,-1),LEN(@input))),'') s,
    IIF(CHARINDEX(',',@input)=0,'',RIGHT(@input,LEN(@input)-CHARINDEX(',',@input))) p
  UNION ALL
  SELECT
    n+1,
    LEFT(p,ISNULL(NULLIF(CHARINDEX(',',p)-1,-1),LEN(p))) s,
    IIF(CHARINDEX(',',p)=0,'',RIGHT(p,LEN(p)-CHARINDEX(',',p))) p
  FROM sCTE
  WHERE p<>''
)
SELECT
  @day1=MAX(CASE WHEN N=1 THEN S END),
  @day2=MAX(CASE WHEN N=2 THEN S END),
  @day3=MAX(CASE WHEN N=3 THEN S END),
  @day4=MAX(CASE WHEN N=4 THEN S END),
  @day5=MAX(CASE WHEN N=4 THEN S END),
  @day6=MAX(CASE WHEN N=4 THEN S END),
  @day7=MAX(CASE WHEN N=4 THEN S END)
FROM sCTE

-- check
SELECT @day1,@day2,@day3,@day4,@day5,@day6,@day7

如果你有一个像monday,tuesday,friday 这样的输入字符串并且你想将它设置为@day2=monday; @day3=tuesday; @day6=friday 的变体

DECLARE
  @day1 varchar(10),
  @day2 varchar(10),
  @day3 varchar(10),
  @day4 varchar(10),
  @day5 varchar(10),
  @day6 varchar(10),
  @day7 varchar(10)

DECLARE @input varchar(100)='monday,tuesday,friday'

SET @day1=IIF(CHARINDEX('sunday',@input)>0,'sunday',NULL)
SET @day2=IIF(CHARINDEX('monday',@input)>0,'monday',NULL)
SET @day3=IIF(CHARINDEX('tuesday',@input)>0,'tuesday',NULL)
SET @day4=IIF(CHARINDEX('wednesday',@input)>0,'wednesday',NULL)
SET @day5=IIF(CHARINDEX('thursday',@input)>0,'thursday',NULL)
SET @day6=IIF(CHARINDEX('friday',@input)>0,'friday',NULL)
SET @day7=IIF(CHARINDEX('saturday',@input)>0,'saturday',NULL)

-- check
SELECT @day1,@day2,@day3,@day4,@day5,@day6,@day7

【讨论】:

  • 有时字符串包含4天那么如何处理变量?字符串包含的 1 - 7(任意数量)天。我们应该为这个应用什么逻辑?
  • 作为变体,您可以添加@day4=MAX(CASE WHEN N=4 THEN S END),...,@day7=MAX(CASE WHEN N=7 THEN S END)。如果您只有 3 天,那么 @day4, ... ,@day7 变量将是 NULL。例如,我在答案中添加了 @day4 变量。
  • 你的输入字符串可以像monday,tuesday,friday这样吗?如果这是真的,在这种情况下会发生什么? @day1=monday; @day2=tuesday; @day3=friday@day2=monday; @day3=tuesday; @day6=friday?
  • 对于我们的特定数据库,他们使用的是可比性级别 110。我现在能做什么?
  • 我刚刚在我的答案中添加了另外两个变体。
【解决方案2】:

创建了一个动态 sql 查询。不知道效率如何。

查询

declare @days as varchar(max) = 'sunday,monday,thursday';

declare @t as table([id] int not null identity(1, 1), [value] varchar(100));
insert into @t([value])
select [Value] from String_Split(@days, ',');

declare @i as int;
select @i = count(*) from @t;

declare @j as int;
set @j = 1;

declare @sql1 as varchar(max) = '';
declare @sql2 as varchar(max) = '';

while(@j <= @i)
begin
  select @sql1 += 'declare @day' + cast(@j as varchar(10)) + ' as varchar(100);'
               +  'set @day' + cast(@j as varchar(10)) + ' = '
               + char(39)
               + (select [value] from @t where [id] = @j) 
               + char(39)
               + ';';

  select @sql2 += '@day' + cast(@j as varchar(10)) 
               + ' as [@day' + cast(@j as varchar(10)) + '] ,';          

  set @j += 1;
end

select @sql2 = 'select ' + left(@sql2, len(@sql2) - 1);

declare @sql as varchar(max) = @sql1 + @sql2;

exec(@sql);

Find a demo here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 2015-01-10
    • 2012-07-31
    • 2014-03-02
    • 2020-07-31
    • 2015-02-26
    • 2020-04-17
    相关资源
    最近更新 更多