数据库环境:SQL SERVER 2005
以前用C/JAVA穷举双色球的所有排列,今天想着换成用SQL实现,只生成一柱双色球。
简单说下双色球的规则,双色球由红色球和蓝色球组成,每注投注号码由6个红色球号码和1个蓝色球号码组成。
红色球号码从1--33中选择;蓝色球号码从1--16中选择。同时,一柱号码中,蓝色球不能出现在红色球里。
规则讲完了,我们来看实现,直接上代码,代码里有注释,应该都能看懂
/*生成1-33个号码的球*/WITH x0 AS ( SELECT number AS ball FROM master.dbo.spt_values WHERE type = 'P' AND number <= 33 AND number >= 1 ),/*随机生成6个红色球*/ x1 AS ( SELECT TOP 6 ball FROM x0 ORDER BY NEWID() ) SELECT redball AS 红色球 , ( /*生成蓝色球*/ SELECT TOP 1 ball FROM x0 WHERE ball <= 16 AND ball NOT IN ( SELECT ball FROM x1 ) ORDER BY NEWID() ) AS 蓝色球 FROM ( /*将红色球排到一行*/ SELECT REPLACE(( SELECT CAST(ball AS VARCHAR) + ',' FROM x1 FOR XML PATH('') ), ',', ' ') AS redball ) t
这样就实现了吗???
没有!!!
这里挖了一个坑,我们先看下意外的结果
蓝色球和红色球出现重号
问题就出现在我用cte生成随机的6个红色球,每次调用x1的时候,这6个数都会随机生成,所以,才会出现这样的结果。
问题已经查明了,我们把6个红色球存到临时表里头,就不会每次调用的时候会发生改变。
更改后的SQL如下:
/*生成1-33号码的球*/SELECT number AS ballINTO #t0FROM master.dbo.spt_valuesWHERE type = 'P' AND number <= 33 AND number >= 1/*生成6个红色球*/ SELECT TOP 6 ballINTO #t1FROM #t0ORDER BY NEWID()SELECT redball AS 红色球 , ( /*生成蓝色球*/ SELECT TOP 1 ball FROM #t0 WHERE ball <= 16 AND ball NOT IN ( SELECT ball FROM #t1 ) ORDER BY NEWID() ) AS 蓝色球FROM ( /*将红色球排到一行*/ SELECT REPLACE(( SELECT CAST(ball AS VARCHAR) + ',' FROM #t1 FOR XML PATH('') ), ',', ' ') AS redball ) t