我是这个论坛的新手,正在寻求有关以下问题的帮助。 我希望从结果集中获得所有可能的排序。 例如
Column1
-------
val1
val2
val3
预期结果
RowNumCoumn Column1
----------- -------
1 Val1
2 Val2
3 Val3
4 Val1
5 Val3
6 Val2
7 Val2
8 Val1
9 Val3
10 Val2
11 Val3
12 Val1
13 Val3
14 Val1
15 Val2
16 Val3
17 Val2
18 Val1
答案 0 :(得分:0)
我认为这是一个非常困难的问题。我的解决方案使用两个递归CTES:
Sub Loop_Example()
Dim Firstrow As Long, Lastrow As Long, Lrow As Long
Dim CalcMode As Long, ViewMode As Long
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
With ActiveSheet
.Select 'select sheet so we can change the window view
ViewMode = ActiveWindow.View 'go to normal view, for speed
ActiveWindow.View = xlNormalView
.DisplayPageBreaks = False 'Turn off Page Breaks
Firstrow = .UsedRange.Cells(1).Row 'Set first & last row
Lastrow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
For Lrow = Lastrow To Firstrow Step -1 'loop bottom to top
With .Cells(Lrow, "A")
If Not IsError(.Value) Then
Select Case .Value
Case Is <> "jelle", "ron", "dave": .EntireRow.Delete
End Select
End If
End With
Next Lrow
End With
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub
(当然,逗号是值的任意定界符。如果值已经有逗号,则可以将其更改为所需的任何内容)。
第一个递归cte(with t as (select * from (values ('a'), ('b'), ('c')) v(col)),
tn as (
select row_number() over (order by col) as n, col
from t
),
cte as (
select ',' + cast(n as varchar(max)) + ',' as ordering,
cast(col as varchar(max)) + ',' as columns,
1 as lev
from tn
union all
select cte.ordering+ cast(tn.n as varchar(max)) + ',' ,
cast(cte.columns + tn.col as varchar(max)) + ',',
lev + 1
from cte join
tn
on cte.ordering not like '%,' + cast(tn.n as varchar(max)) + ',%'
),
orderings as (
select top (1) with ties cte.*
from cte
order by lev desc
),
splits as (
select ordering, columns,
left(columns, charindex(',', columns) - 1) as val,
stuff(columns, 1, charindex(',', columns) , '') as rest,
1 as lev
from orderings
union all
select ordering, columns,
left(rest, charindex(',', rest) - 1) as val,
stuff(rest, 1, charindex(',', rest), '') as rest,
lev + 1
from splits
where rest like '%,%'
)
select *
from splits;
order by ordering, lev;
)计算所有可能的顺序-但每个顺序仅一行。它遍历数据,一次构造所有可能的组合。 cte cte
实际上是具有完整组合(在这种情况下,长度为3)的cte。您可能会发现orderings
具有您要查找的信息。
然后,第二个递归cte(orderings
)扩展拆分以使结果返回到行中。
这是一个有趣的练习,但是我不会在只有几行的表上运行这样的代码。输出行数为n * n! (n阶乘)。增长非常快。
我还应该指出,这种逻辑可能更适合在应用程序级别而不是SQL中实现。但这是一个有趣的SQL问题。毕竟,解决方案为n * n的问题并不多!原始表中的行。
答案 1 :(得分:0)
鉴于预期的结果,这是一个奇怪的挑战。
但是您可以通过自我联接来实现。
可用于查找3个值的所有组合。
然后取消显示该结果以得到预期结果。
示例代码段:
declare @Table table (Column1 varchar(30));
insert into @Table (Column1) values
('val1'),
('val2'),
('val3');
select
row_number() over (order by rn, Col) as RowNumColumn,
Val as Column1
from
(
select
t1.Column1 as Col1,
t2.Column1 as Col2,
t3.Column1 as Col3,
row_number() over (order by t1.Column1, t2.Column1, t3.Column1) as rn
from @Table as t1
left join @Table as t2 on t2.Column1 != t1.Column1
left join @Table as t3 on t3.Column1 not in (t1.Column1, t2.Column1)
) src
UNPIVOT (
Val
FOR Col IN ([Col1], [Col2], [Col3])
) as unpvt
order by RowNumColumn;