在SQL Server中生成组合

时间:2017-01-25 13:50:45

标签: sql-server

我需要从数字串中生成组合 3,4,5,6,7数字组合

例如来自此字符串

01;05;06;03;02;10;11;

这里有7个数字。对于3位数的35个组合将在那里,它应该按字符串中的订单号顺序排列。 喜欢

01;05;06;|
01;05;03;|
01;05;02;|
01;05;10;|
01;05;11;|
01;06;03;|
01;06;02;|
01;06;10;|
01;06;11;|
01;03;02;|
01;03;10;|
01;03;11;|
01;02;10;|
01;02;11;|
01;10;11;|

05;06;03;|
05;06;02;|
05;06;10;|
05;06;11;|

05;03;02;|
05;03;10;|
05;03;11;|
05;02;10;|
05;02;11;|
05;10;11;|

06;03;02;|
06;03;10;|
06;03;11;|
06;02;10;|
06;02;11;|
06;10;11;|

03;02;10;|
03;02;11;|

03;10;11;|

02;10;11;|

2 个答案:

答案 0 :(得分:1)

分割字符串后,您可以使用两个内连接执行此操作。

rextester:http://rextester.com/JJGKI77804

测试的String Splitter:

/* Jeff Moden's http://www.sqlservercentral.com/articles/Tally+Table/72993/ */
create function dbo.DelimitedSplitN4K (@pString nvarchar(4000), @pDelimiter nchar(1))
returns table with schemabinding as
return
  with e1(n) as (
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all select 1
  )
  , e2(n) as (select 1 from e1 a, e1 b)
  , e4(n) as (select 1 from e2 a, e2 b)
  , cteTally(n) as (select top (isnull(datalength(@pString)/2,0))
      row_number() over (order by (select null)) from e4)
  , cteStart(n1) as (select 1 union all 
      select t.n+1 from cteTally t where substring(@pString,t.n,1) = @pDelimiter)
  , ctelen(n1,l1) as(select s.n1
  ,   isnull(nullif(charindex(@pDelimiter,@pString,s.n1),0)-s.n1,4000)
    from cteStart s
  )
 select Itemnumber = row_number() over(order by l.n1)
      , Item       = substring(@pString, l.n1, l.l1)
   from ctelen l;
go

查询

declare @str nvarchar(4000)= '01;05;06;03;02;10;11;';
with cte as (
  select ItemNumber, Item 
  from dbo.DelimitedSplitN4K(@str,';') 
  where Item != ''
)
select combo=a.Item+';'+b.Item+';'+c.Item
  from cte as a
    inner join cte as b on a.ItemNumber<b.ItemNumber
    inner join cte as c on b.ItemNumber<c.ItemNumber;
  order by a.ItemNumber, b.ItemNumber, c.ItemNumber

ItemNumber结果排序:

01;05;06
01;05;03
01;05;02
01;05;10
01;05;11
01;06;03
01;06;02
01;06;10
01;06;11
01;03;02
01;03;10
01;03;11
01;02;10
01;02;11
01;10;11
05;06;03
05;06;02
05;06;10
05;06;11
05;03;02
05;03;10
05;03;11
05;02;10
05;02;11
05;10;11
06;03;02
06;03;10
06;03;11
06;02;10
06;02;11
06;10;11
03;02;10
03;02;11
03;10;11
02;10;11

如果要返回单个字符串,则管道分隔:

with cte as (
  select ItemNumber, Item 
  from dbo.DelimitedSplitN4K(@str,';') 
  where Item != ''
)
select combo=stuff(
  (select '|'+a.Item+';'+b.Item+';'+c.Item
    from cte as a
      inner join cte as b on a.ItemNumber<b.ItemNumber
      inner join cte as c on b.ItemNumber<c.ItemNumber
    order by a.ItemNumber, b.ItemNumber, c.ItemNumber
    for xml path (''), type).value('.','nvarchar(max)')
  ,1,1,'')

结果:

01;05;06|01;05;03|01;05;02|01;05;10|01;05;11|01;06;03|01;06;02|01;06;10|01;06;11|01;03;02|01;03;10|01;03;11|01;02;10|01;02;11|01;10;11|05;06;03|05;06;02|05;06;10|05;06;11|05;03;02|05;03;10|05;03;11|05;02;10|05;02;11|05;10;11|06;03;02|06;03;10|06;03;11|06;02;10|06;02;11|06;10;11|03;02;10|03;02;11|03;10;11|02;10;11

拆分字符串参考:

答案 1 :(得分:1)

我有几乎相同的查询,但结果有所不同 请检查

/*
create table Combination (id char(2))
insert into Combination values ('01'),('05'),('06'),('03'),('02'),('10'),('11')
*/
select c1.id, c2.id, c3.id, c1.id + ';' + c2.id + ';' + c3.id Combination
from Combination c1, Combination c2, Combination c3
where
  c2.id between c1.id and c3.id
  and c1.id <> c2.id
  and c2.id <> c3.id
order by c1.id, c2.id, c3.id

输出

enter image description here