此 SQL 将计算不重复的排列:
WITH recurse(Result, Depth) AS
(
SELECT CAST(Value AS VarChar(100)), 1
FROM MyTable
UNION ALL
SELECT CAST(r.Result + '+' + a.Value AS VarChar(100)), r.Depth + 1
FROM MyTable a
INNER JOIN recurse r
ON CHARINDEX(a.Value, r.Result) = 0
)
SELECT Result
FROM recurse
WHERE Depth = (SELECT COUNT(*) FROM MyTable)
ORDER BY Result
如果MyTable
包含 9 行,则需要一些时间来计算,但它会返回 362,880 行。
更新说明:
该WITH
语句用于定义递归公用表表达式。实际上,该WITH
语句循环多次执行 aUNION
直到递归完成。
SQL 的第一部分设置起始记录。假设 3 行名为“A”、“B”和“C” MyTable
,这将生成以下行:
Result Depth
------ -----
A 1
B 1
C 1
然后下一个 SQL 块执行第一级递归:
SELECT CAST(r.Result + '+' + a.Value AS VarChar(100)), r.Depth + 1
FROM MyTable a
INNER JOIN recurse r
ON CHARINDEX(a.Value, r.Result) = 0
这将获取到目前为止生成的所有记录(将在recurse
表中)并将它们再次连接到所有记录MyTable
。该ON
子句过滤记录列表MyTable
以仅返回该行排列中不存在的记录。这将导致这些行:
Result Depth
------ -----
A 1
B 1
C 1
A+B 2
A+C 2
B+A 2
B+C 2
C+A 2
C+B 2
然后递归循环再次给出这些行:
Result Depth
------ -----
A 1
B 1
C 1
A+B 2
A+C 2
B+A 2
B+C 2
C+A 2
C+B 2
A+B+C 3
A+C+B 3
B+A+C 3
B+C+A 3
C+A+B 3
C+B+A 3
此时,递归停止,因为UNION
不会再创建任何行,因为CHARINDEX
将永远是0
。
Depth
最后一个 SQL 过滤计算列与 中的记录数匹配的所有结果行MyTable
。这会抛出除最后一个递归深度生成的行之外的所有行。所以最终结果将是这些行:
Result
------
A+B+C
A+C+B
B+A+C
B+C+A
C+A+B
C+B+A