首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

全排列解决方案

2013-08-04 
全排列USE tempdb GOIF OBJECT_ID(TEST) IS NOT NULLDROP TABLE TESTGOCREATE TABLE TEST(NUMINT, )GO

全排列

USE tempdb 
GO
IF OBJECT_ID('TEST') IS NOT NULL
  DROP TABLE TEST;
GO
CREATE TABLE TEST
(
  NUMINT,
 );
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 求优化
*/

[解决办法]
引用:
恩,那换个问题,求 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 无法实现别的组合,动态的还真不知道用什么办法实现...
[解决办法]
返回三百多万数据,优化余地不大,可以使用位运算:
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 。。。快点,而且会生成一个串行计划,原来的应该是并行计划。

热点排行