Tsql 在t-sql中生成具有可变长度的给定字符集的所有可能排列
我编写了下面的脚本来生成指定字符集的所有可能排列 在允许在运行时指定长度的同时,有没有一种方法可以有效地做到这一点Tsql 在t-sql中生成具有可变长度的给定字符集的所有可能排列,tsql,Tsql,我编写了下面的脚本来生成指定字符集的所有可能排列 在允许在运行时指定长度的同时,有没有一种方法可以有效地做到这一点 DECLARE @string NVARCHAR(MAX) SELECT @string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; DECLARE @Chars TABLE ( C CHAR(1) PRIMARY KEY ) DECLARE @N INT SET @N = 1 WHILE @N <= LEN(@stri
DECLARE @string NVARCHAR(MAX)
SELECT @string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE @Chars TABLE (
C CHAR(1) PRIMARY KEY
)
DECLARE @N INT
SET @N = 1
WHILE @N <= LEN(@string) BEGIN
INSERT @Chars (
C
) VALUES (
SUBSTRING(@string, @N, 1)
)
SET @N = @N + 1
END
--SELECT * FROM @Chars
SELECT
A.C + B.C + C.C
FROM @Chars A, @Chars B, @Chars C
ORDER BY
A.C,
B.C,
C.C
如果您使用的是SQL Server 2005或更高版本,则可以尝试递归CTE:
DECLARE @length int;
SET @length = 3;
WITH expanded AS (
SELECT
C = SUBSTRING(@string, N, 1)
FROM numbers
WHERE number BETWEEN 1 AND LEN(@string)
),
permutations AS (
SELECT
S = CAST(C AS nvarchar(max)),
L = 1
FROM expanded
UNION ALL
SELECT
S = S + C,
L = L + 1
FROM permutations p
CROSS JOIN expanded e
WHERE L < @length
)
SELECT *
FROM permutations
WHERE L = @length
;
其中n是0到32767之间的整数值,表示递归CTE的最大迭代次数,上面提到的100是默认值。Nil实际上意味着没有限制,应该谨慎使用
您可以尝试此查询并使用它,我将@字符串减少为仅8个字符,以便能够为@length指定更多不同的值,而无需使查询返回太多行,并且还将numbers表定义为a的子集。在收到与可能的排列数量相关的注释后,我意识到对字符集的长度以及指定的长度应该有非常严格的限制 考虑到允许的长度非常小,我认为在脚本中使用条件没有什么害处。。。像这样:
DECLARE
@string NVARCHAR(40), --limit the length of the character set to 40
@length INT -- the limit for this is in a validation check below
SELECT
@string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
@length = 2
IF (@length < 1 OR @length > 4) BEGIN
RAISERROR('Invalid length specified. This function only supports lengths from 1 to 4', 16, 1)
END
DECLARE @Chars TABLE (
C CHAR(1) PRIMARY KEY
)
;WITH numbers AS (
SELECT TOP(LEN(@string)) number
FROM master..spt_values
WHERE type = 'P'
AND number != 0
)
INSERT @Chars (
C
)
SELECT
C = SUBSTRING(@string, number, 1)
FROM numbers
IF (@length = 1) BEGIN
SELECT C FROM @Chars ORDER BY C
END ELSE IF (@length = 2) BEGIN
SELECT A.C + B.C
FROM @Chars A, @Chars B
ORDER BY A.C, B.C
END ELSE IF (@length = 3) BEGIN
SELECT A.C + B.C + C.C
FROM @Chars A, @Chars B, @Chars C
ORDER BY A.C, B.C, C.C
END ELSE IF (@length = 4) BEGIN
SELECT A.C + B.C + C.C + D.C
FROM @Chars A, @Chars B, @Chars C, @Chars D
ORDER BY A.C, B.C, C.C, D.C
END
是否要将排列作为包含单个字符的列返回?这意味着列数可变,而这又意味着动态脚本。一个包含指定长度字符串的单列可以吗?@AndriyM:可以。我也编辑了我的问题来说明这一点。谢谢。+1使用笛卡尔积生成排列,非常聪明,但一旦达到10+位数,这将对数据库造成负担…如果字符集始终为36个字符,则可以计算排列的数量,然后创建从0到n的排列,从10到36,用零填充左边。前几天我刚做了这个-但是对于一个给定的整数-不是一系列的整数。。。从base10到base36转换角度接近它并不难。。。固定注释,将26个字符更改为3636个字符@4位数=1.7Mil排列;5位=60Mil;6位数字=2.2比尔;等等。字符集中的字符和数字的上限是多少?这个解决方案确实有效,但我不喜欢它生成长度等于或小于指定长度的所有排列。随着指定长度和/或字符集长度的增长。。。。这不能很好地扩展。
DECLARE
@string NVARCHAR(40), --limit the length of the character set to 40
@length INT -- the limit for this is in a validation check below
SELECT
@string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
@length = 2
IF (@length < 1 OR @length > 4) BEGIN
RAISERROR('Invalid length specified. This function only supports lengths from 1 to 4', 16, 1)
END
DECLARE @Chars TABLE (
C CHAR(1) PRIMARY KEY
)
;WITH numbers AS (
SELECT TOP(LEN(@string)) number
FROM master..spt_values
WHERE type = 'P'
AND number != 0
)
INSERT @Chars (
C
)
SELECT
C = SUBSTRING(@string, number, 1)
FROM numbers
IF (@length = 1) BEGIN
SELECT C FROM @Chars ORDER BY C
END ELSE IF (@length = 2) BEGIN
SELECT A.C + B.C
FROM @Chars A, @Chars B
ORDER BY A.C, B.C
END ELSE IF (@length = 3) BEGIN
SELECT A.C + B.C + C.C
FROM @Chars A, @Chars B, @Chars C
ORDER BY A.C, B.C, C.C
END ELSE IF (@length = 4) BEGIN
SELECT A.C + B.C + C.C + D.C
FROM @Chars A, @Chars B, @Chars C, @Chars D
ORDER BY A.C, B.C, C.C, D.C
END