2011-11-23 64 views
2

我需要一个可以在(或作为)函数中使用的查询,并检索n个值的所有排列。我需要长度为k的所有排列,其中k = 1..n。编辑#1:扩展样本输入和结果如此输入有3个值而不是2 - 但是,输入值的数量可能会从1到n变化。获取k值的所有排列(k = 1 ... n)

实施例:

输入:表中的多个行

一个列值
Value (nvarchar(500)) 
    ------ 
    Ann 
    John 
    Mark 

编辑#2:我可以与任何下列产出

的活

输出#1:表值连接在一列中

Ann 
    John 
    Ann,John 
    John,Ann 
    Ann,Mark 
    Mark,Ann 
    John,Mark 
    Mark,John 
    Ann,John,Mark 
    Ann,Mark,John 
    John,Ann,Mark 
    John,Mark,Ann 
    Mark,Ann,John 
    Mark,John,Ann 

输出#2:带有permutat的id表离子/组合,价值和为了

id value order 
    -------------------- 
    1  Ann  1 
    2  John  1 
    3  Ann  1 
    3  John  2 
    4  John  1 
    5  Ann  2 

注:

  • 必须SQL服务器上工作2008 R2
  • 必须函数内工作
  • 预期不同元件在输入绝不能超过的最大数目5 - 如果这对于性能或任何其他原因很重要
  • 输入表中的值列不可能超过200个字符的长度 - 如果这对性能或任何o疗法原因

很多搜​​索在互联网上,我发现Generating Permutations in T-SQL论坛主题,但我并没有设法修改它给预期的输出格式,以及迫使它使K = 1的后... n排列也。

对于大部分以非SQL语言编写的类似问题,有很多解决方案,但我找不到能够帮助我解决这个特定问题的解决方案。

+0

你尝试过什么?也许一个n-way自我加入约束选择的领域是不相等的彼此? –

+0

@RaymondHettinger:我试图从指定的链接修改代码。还试图修改其他各种解决方案,但很多文章的作者误解了排列和组合。这是两者的结合。 N-连接像多个交叉连接?不,它不起作用,因为我不知道数值的前面(如问题k = 1 ... n所述)。 –

+0

然后可能会很难过。我不知道任何返回可变长度字段的参数化SQL查询。 –

回答

8
;WITH Names(Name) As 
(
SELECT 'Ann' UNION ALL 
SELECT 'John' UNION ALL 
SELECT 'Mark' 
), R(Name,Lvl) AS 
(
SELECT CAST(',' + Name AS VARCHAR(MAX)), 1 
FROM Names 
UNION ALL 
SELECT R.Name + ',' + N.Name, Lvl + 1 
FROM R JOIN Names N ON R.Name + ',' NOT LIKE '%,' + N.Name + ',%' 
) 
SELECT STUFF(Name,1,1,'') AS Name 
FROM R 
ORDER BY Lvl, Name 

返回

Name 
------------------------------ 
Ann 
John 
Mark 
Ann,John 
Ann,Mark 
John,Ann 
John,Mark 
Mark,Ann 
Mark,John 
Ann,John,Mark 
Ann,Mark,John 
John,Ann,Mark 
John,Mark,Ann 
Mark,Ann,John 
Mark,John,Ann 
+0

Martin,这是完美的解决方案,非常感谢!似乎我过分复杂的T-SQL代码。 –

+0

@FilipPopović我假设你的实际数据不包含任何对LIKE运算符有特殊意义的逗号或字符。如果情况并非如此,那么可能需要调整。 –

+0

Martin,数据是某个表的列名。在我的情况下,将会有下划线的列。我做了一个快速测试,对于我的特定测试用例,它正在工作,但如果您可以调整您的查询,我将非常感激。提前致谢。 –

相关问题