全排列

amazeyeli 2013-07-19 02:31:06
USE tempdb 
GO
IF OBJECT_ID('TEST') IS NOT NULL
DROP TABLE TEST;
GO
CREATE TABLE TEST
(
NUM INT,
);
GO
INSERT INTO TEST VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
GO
----------------------------------------
SELECT *
FROM TEST A
JOIN TEST B
ON A.NUM <> B.NUM
JOIN TEST C
ON A.NUM <> C.NUM AND B.NUM <> C.NUM
JOIN TEST D
ON A.NUM <> D.NUM AND B.NUM <> D.NUM AND C.NUM <> D.NUM
JOIN TEST E
ON A.NUM <> E.NUM AND B.NUM <> E.NUM AND C.NUM <> E.NUM AND D.NUM <> E.NUM
JOIN TEST F
ON A.NUM <> F.NUM AND B.NUM <> F.NUM AND C.NUM <> F.NUM AND D.NUM <> F.NUM AND E.NUM <> F.NUM
JOIN TEST G
ON A.NUM <> G.NUM AND B.NUM <> G.NUM AND C.NUM <> G.NUM AND D.NUM <> G.NUM AND E.NUM <> G.NUM AND F.NUM <> G.NUM
JOIN TEST H
ON A.NUM <> H.NUM AND B.NUM <> H.NUM AND C.NUM <> H.NUM AND D.NUM <> H.NUM AND E.NUM <> H.NUM AND F.NUM <> H.NUM AND G.NUM <> H.NUM
JOIN TEST I
ON A.NUM <> I.NUM AND B.NUM <> I.NUM AND C.NUM <> I.NUM AND D.NUM <> I.NUM AND E.NUM <> I.NUM AND F.NUM <> I.NUM AND G.NUM <> I.NUM AND H.NUM <> I.NUM
----------------------------------------
/*
结果:全排列 10!=3628800 求优化
*/
...全文
193 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
amazeyeli 2013-07-23
  • 打赏
  • 举报
回复
谢谢各位高手
Vidor 2013-07-21
  • 打赏
  • 举报
回复
返回三百多万数据,优化余地不大,可以使用位运算:
with # as
(
	select * from (values(1),(2),(4),(8),(16),(32),(64),(128),(256),(512)) t(n)
)
/*
select * from # a -- C(10,3) = 120
join # b on a.n<b.n
join # c on b.n<c.n
--join # d on c.n<d.n
--join # e on d.n<e.n
--join # f on e.n<f.n
--join # g on f.n<g.n
--join # h on g.n<h.n
--join # i on h.n<i.n
*/
select * from # a -- A(10,3) = 720
join # b on a.n&b.n=0
join # c on a.n|b.n&c.n=0
--join # d on a.n|b.n|c.n&d.n=0
--join # e on a.n|b.n|c.n|d.n&e.n=0
--join # f on a.n|b.n|c.n|d.n|e.n&f.n=0
--join # g on a.n|b.n|c.n|d.n|e.n|f.n&g.n=0
--join # h on a.n|b.n|c.n|d.n|e.n|f.n|g.n&h.n=0
--join # i on a.n|b.n|c.n|d.n|e.n|f.n|g.n|h.n&i.n=0
比 AND AND 。。。快点,而且会生成一个串行计划,原来的应该是并行计划。
哥眼神纯洁不 2013-07-20
  • 打赏
  • 举报
回复
引用 2 楼 amazeyeli 的回复:
恩,那换个问题,求 C10,3 所有组合 C10,3 = 10!/(10-3)!/3! = 720 / 6 = 120

declare @a int,@b int,@c int
set @a=1
set @b=1
set @c=1
declare @t table(a int,b int,c int)
while (@a<11)
begin
set @b=1
  while (@b<11)
  begin
  set @c=1
    while (@c<11)  
    begin
    if(@a!=@b and @c!=@b and @a!=@c) and 
    (select count(1) from @t where 
    (convert(varchar,a)+','+convert(varchar,b)+','+convert(varchar,c)) in(
    (convert(varchar,@a)+','+convert(varchar,@c)+','+convert(varchar,@b)),
    (convert(varchar,@b)+','+convert(varchar,@a)+','+convert(varchar,@c)),
    (convert(varchar,@b)+','+convert(varchar,@c)+','+convert(varchar,@a)),
    (convert(varchar,@c)+','+convert(varchar,@a)+','+convert(varchar,@b)),
    (convert(varchar,@c)+','+convert(varchar,@b)+','+convert(varchar,@a))
    ))=0
    insert into @t 
    select @a,@b,@c
    set @c=@c+1
    end
    set @b=@b+1
    end
    set @a=@a+1
    end
    select * from @t
这个可以实现C 10,3 无法实现别的组合,动态的还真不知道用什么办法实现...
kobemadi 2013-07-20
  • 打赏
  • 举报
回复
花了49秒,的确要优化。观望。。
amazeyeli 2013-07-20
  • 打赏
  • 举报
回复
恩,那换个问题,求 C10,3 所有组合 C10,3 = 10!/(10-3)!/3! = 720 / 6 = 120
Andy__Huang 2013-07-19
  • 打赏
  • 举报
回复
这好象是计算彩票全排序,不知道有没有再优化

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧