数据库环境:SQL SERVER2008R2
先说一下需求:实现1,2,3的排列组合,即123,132,213,231,312,321。
哈哈,你没看错,需求这是这么短短的一句话。
我想到了2个方法,都可以实现需求。下面我分别介绍这2种实现方法。
方法一:建一个表xx,往xx表中插入1,2,3自然数列,简单起见,把自然数改成字符串,
然后xx表和xx表进行FULL JOIN(全外连接)得到结果集tmp,结果集tmp再和xx表进行LEFT JOIN(左连接),
关联的条件是当前xx表的数据不存在结果集tmp中,这个可以通过MSSQL内置函数CHARINDEX实现。
/*数据准备*/ WITH x0 AS ( SELECT ‘1‘ AS hid UNION ALL SELECT ‘2‘ AS hid UNION ALL SELECT ‘3‘ AS hid --UNION ALL --SELECT ‘4‘ AS hid ) /*计算、输出*/ SELECT a.hid + b.hid AS hid FROM ( SELECT a.hid + b.hid AS hid FROM x0 a FULL JOIN x0 b ON b.hid <> a.hid ) a LEFT JOIN x0 b ON CHARINDEX(b.hid, a.hid, 1) = 0 ORDER BY 1
方法一看起来简单明了,用不着再解释了。现在我们来看一下方法二的实现:
通过CTE实现递归,把1,2,3的所有组合都枚举,最后在外层把字符串长度为3的组合给过滤出来即可。
/*数据准备*/ WITH x0 AS ( SELECT CONVERT(VARCHAR(10),1) AS hid UNION ALL SELECT CONVERT(VARCHAR(10),2) AS hid UNION ALL SELECT CONVERT(VARCHAR(10),3) AS hid --UNION ALL --SELECT CONVERT(VARCHAR(10),4) AS hid ) SELECT * INTO xx FROM x0 WITH x1 AS ( SELECT hid FROM xx WHERE LEN(hid) <= 3 UNION ALL SELECT CONVERT(VARCHAR(10), a.hid + b.hid) AS hid FROM xx a INNER JOIN x1 b ON CHARINDEX(a.hid, b.hid, 1) = 0 ) SELECT * FROM x1 WHERE LEN(hid) = 3 ORDER BY hid
好了,方法二也实现了。这里要注意一点,就是插入xx表要指定数据类型及长度,在拼接的时候,也要转换一下格式。不然,
会提示“类型不匹配”错误。
OK,我把结果贴一下。
现在简单总结一下这2种实现方法,方法一技巧性比较强,也很简单,容易理解,缺点是如果要增加到4位数,那么,就要在外面多套一些循环。
方法二用到了递归,理解起来有点困难,但相对于方法一更灵活,如果增加到更多的数,只需改一下代码中相应的数字即可。
(本文完)
时间: 2024-11-07 11:22:44