T-SQL 中结果集的幂集(所有组合)
powerset(all combinations) of a resultset in T-SQL
我需要一个 t-sql 代码来获取结果集的幂集。
示例输入:
ColumnName
1
2
3
Example Output(one columns as nvarchar) :
1
2
3
1,2
1,3
2,3
1,2,3
输出集可能包含重复值,例如 (1,3 vs 3,1)。
你可以使用这个并获得完整的动力装置。
好好享受吧。
--EXEC PowerSet 'A,B,C,D'
Create PROCEDURE PowerSet(@Members NVARCHAR(64))
As
Begin
Declare @SubSet NVARCHAR(Max),
@SubSetCount int,
@Counter1 int,
@Counter2 int,
@ID int
Create table #Members
(
ID int IDENTITY(1,1) PRIMARY KEY,
Member NVARCHAR(50)
)
Create table #PowerSets
(
SubSet NVARCHAR(50)
)
-- Start Convert @Members To Table #Members
Set @Members=@Members+','
While @Members<>''
Begin
Insert Into #Members(Member)
Values(Left(@Members,CHARINDEX(',',@Members)-1))
Set @Members=RIGHT(@Members,LEN(@Members)-CHARINDEX(',',@Members))
End
-- End Convert @Members To Table #Members
-- Start Calculat PowerSet
Set @SubSetCount=POWER(2,(Select Count(*) From #Members))
Set @Counter1=0
while @Counter1<@SubSetCount
Begin
Set @Counter2=@Counter1
Set @ID=1
Set @SubSet='{'
While @Counter2>0
Begin
If CONVERT(char(1), @Counter2 % 2)=1
Set @SubSet=@SubSet+iif(@SubSet<>'{',',','')+(Select Member From #Members Where ID=@ID)
Set @Counter2 = CONVERT(int, (@Counter2 / 2))
Set @ID=@ID+1
End
Set @Counter1=@Counter1+1
Insert into #PowerSets(SubSet) values(@SubSet+'}')
End
-- End Calculat PowerSet
Select *
From #PowerSets
Order By Len(SubSet),SubSet
Drop Table #PowerSets
Drop Table #Members
End
假设您想获得一个名为@items 的 table 的幂集,其中只有一个名为 name 的列。您可以获得这样的动力装置。根据需要更改 table 名称、列名和列类型。如果您想将每个子集作为一行,那么只需在末尾按 sk.k 分组
declare @itemKeys table(
Name varchar(255),
K int
)
insert into @itemKeys(Name, K)
select Name, POWER(2,ROW_NUMBER()OVER(ORDER BY Name)-1)
from @items
declare @setKeys table(
k int
)
insert into @setKeys(k)
select TOP(POWER(2,@n)) RANK()OVER(ORDER BY object_id)-1 as k
from sys.all_objects
select sk.K as SetKey, ik.Name
from @setKeys sk
join @itemKeys ik on ik.K & sk.K = ik.K
order by sk.K, ik.K
我需要一个 t-sql 代码来获取结果集的幂集。
示例输入:
ColumnName
1
2
3
Example Output(one columns as nvarchar) :
1
2
3
1,2
1,3
2,3
1,2,3
输出集可能包含重复值,例如 (1,3 vs 3,1)。
你可以使用这个并获得完整的动力装置。
好好享受吧。
--EXEC PowerSet 'A,B,C,D'
Create PROCEDURE PowerSet(@Members NVARCHAR(64))
As
Begin
Declare @SubSet NVARCHAR(Max),
@SubSetCount int,
@Counter1 int,
@Counter2 int,
@ID int
Create table #Members
(
ID int IDENTITY(1,1) PRIMARY KEY,
Member NVARCHAR(50)
)
Create table #PowerSets
(
SubSet NVARCHAR(50)
)
-- Start Convert @Members To Table #Members
Set @Members=@Members+','
While @Members<>''
Begin
Insert Into #Members(Member)
Values(Left(@Members,CHARINDEX(',',@Members)-1))
Set @Members=RIGHT(@Members,LEN(@Members)-CHARINDEX(',',@Members))
End
-- End Convert @Members To Table #Members
-- Start Calculat PowerSet
Set @SubSetCount=POWER(2,(Select Count(*) From #Members))
Set @Counter1=0
while @Counter1<@SubSetCount
Begin
Set @Counter2=@Counter1
Set @ID=1
Set @SubSet='{'
While @Counter2>0
Begin
If CONVERT(char(1), @Counter2 % 2)=1
Set @SubSet=@SubSet+iif(@SubSet<>'{',',','')+(Select Member From #Members Where ID=@ID)
Set @Counter2 = CONVERT(int, (@Counter2 / 2))
Set @ID=@ID+1
End
Set @Counter1=@Counter1+1
Insert into #PowerSets(SubSet) values(@SubSet+'}')
End
-- End Calculat PowerSet
Select *
From #PowerSets
Order By Len(SubSet),SubSet
Drop Table #PowerSets
Drop Table #Members
End
假设您想获得一个名为@items 的 table 的幂集,其中只有一个名为 name 的列。您可以获得这样的动力装置。根据需要更改 table 名称、列名和列类型。如果您想将每个子集作为一行,那么只需在末尾按 sk.k 分组
declare @itemKeys table(
Name varchar(255),
K int
)
insert into @itemKeys(Name, K)
select Name, POWER(2,ROW_NUMBER()OVER(ORDER BY Name)-1)
from @items
declare @setKeys table(
k int
)
insert into @setKeys(k)
select TOP(POWER(2,@n)) RANK()OVER(ORDER BY object_id)-1 as k
from sys.all_objects
select sk.K as SetKey, ik.Name
from @setKeys sk
join @itemKeys ik on ik.K & sk.K = ik.K
order by sk.K, ik.K