【问题标题】:Get all permutations of k values (k = 1...n)获取 k 值的所有排列 (k = 1...n)
【发布时间】:2011-11-23 08:47:32
【问题描述】:

我需要一个可以在(或作为)函数中使用并检索 n 值的所有排列的查询。我需要所有长度为 k 的排列,其中 k = 1..n。

EDIT#1:扩展样本输入和结果,因此输入有 3 个值而不是 2 个 - 但是,输入值的数量可能从 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:id 为排列/组合、值和顺序的表

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

注意事项:

  • 必须在 SQL Server 2008 R2 上工作
  • 必须在函数内工作
  • 输入中预期的不同元素的最大数量不得超过 5 - 如果这对性能或任何其他原因很重要
  • 输入表中的值列的长度不可能超过 200 个字符 - 如果这对性能或任何其他原因很重要

在互联网上进行大量搜索后,我找到了Generating Permutations in T-SQL 论坛主题,但我没有设法对其进行修改以提供预期的输出格式以及强制它使 k = 1...n 排列也.

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

【问题讨论】:

  • 你试过什么?也许是带有约束的 n 路自连接,所选字段彼此不相等?
  • @RaymondHettinger:我尝试从相关链接中修改代码。还尝试修改各种其他解决方案,但许多文章的作者误解了排列和组合。这是两者的混合。 N-join 像多个交叉连接?不,它不起作用,因为我不知道前期值的数量(如问题 k=1...n 中所述)。
  • 那可能运气不好。我不知道任何返回可变长度字段数的参数化 SQL 查询。
  • @RaymondHettinger:我知道无法编写 varible-number-of-return-columns 查询。我需要一列中指定的串联值。但我可以接受将返回三个字段的解决方案:排列的 id、排列中的值和顺序,因此我可以轻松识别排列中的值(只需编辑我的帖子以包含此输出)
  • 您需要查询吗?存储过程呢?

标签: sql-server-2008 tsql permutation combinations


【解决方案1】:
;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

【讨论】:

  • Martin,这是完美的解决方案,非常感谢!似乎我的 T-SQL 代码过于复杂了。
  • @FilipPopović 我假设您的实际数据不包含任何对LIKE 运算符具有特殊意义的逗号或字符。如果不是这种情况,则可能需要调整。
  • Martin,data 是某个表的列名。就我而言,会有带有下划线的列。我做了一个快速测试,对于我的特定测试用例,它正在工作,但如果您可以调整您的查询,我将不胜感激。提前致谢。
  • @FilipPopović - 只需将连接条件更改为FROM R JOIN Names N ON CHARINDEX(',' + N.Name + ',',R.Name + ',',1) = 0
猜你喜欢
  • 1970-01-01
  • 2014-11-19
  • 2011-02-21
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 2013-11-08
相关资源
最近更新 更多