如何在sql server中从长度为n的单词构建2 ^ n更改单词

joz*_*ozi 7 sql t-sql sql-server string sql-server-2008

我需要在sql server中使用一个函数来构建下面示例中的所有更改的单词; 对于长度为n的输入字必须构建2 ^ n改变的字; 例如,如果函数的输入是

"I"
Run Code Online (Sandbox Code Playgroud)

函数的输出应该是

I
-   
Run Code Online (Sandbox Code Playgroud)

函数的输入是

"am"
Run Code Online (Sandbox Code Playgroud)

函数的输出应该是

am
-m
a-
--
Run Code Online (Sandbox Code Playgroud)

函数的输入是

"sql"
Run Code Online (Sandbox Code Playgroud)

函数的输出应该是

sql
-ql
s-l
sq-
--l
s--
-q-
--- 
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 9

您可以使用数字表(master..spt_values)和stuff循环执行此操作.

declare @Word varchar(10) = 'sql'

declare @T table
(
  Word varchar(10)
)

insert into @T values (@Word)

while not exists(select *
                 from @T 
                 where Word = replicate('-', len(@Word)))
begin              
  insert into @T(Word)
  select distinct stuff(T.Word, N.number, 1, '-')
  from @T as T
    cross join
       master..spt_values as N
  where N.type = 'P' and
        N.number between 1 and len(@Word) and
        stuff(T.Word, N.number, 1, '-') not in (select Word from @T)
end        

select *
from @T
Run Code Online (Sandbox Code Playgroud)

http://data.stackexchange.com/stackoverflow/q/122334/

或者您可以使用reqursive CTE

declare @Word varchar(10) = 'sql'

;with C as
(
  select @Word as Word,
         0 as Iteration
  union all
  select cast(stuff(Word, N.number, 1, '-') as varchar(10)),
         Iteration + 1
  from C
    cross join
       master..spt_values as N
  where N.type = 'P' and
        N.number between 1 and len(@Word) and
        Iteration < len(@Word)
)
select distinct Word
from C
Run Code Online (Sandbox Code Playgroud)

http://data.stackexchange.com/stackoverflow/q/122337/

更新

正如OP在评论中所指出的那样,递归CTE版本非常慢.使用带有7个字母的单词,CTE返回了960800行.

  • 第二个答案是好的,但"示例"输入字符串的时间是28秒,第一个答案非常好,"示例"输入字符串的时间是0秒 (2认同)

Con*_*rix 6

这个递归CTE

declare @input varchar(25)

set @input = 'SQL'
;WITH cte 
     AS (SELECT Stuff(@input, v.NUMBER, 1, '-') OUTPUT, 
                0                               LEVEL 
         FROM   MASTER..spt_values v 
         WHERE  TYPE = 'P' 
                AND NUMBER BETWEEN 1 AND Len(@input) 
         UNION ALL 
         SELECT Stuff(cte.OUTPUT, v.NUMBER, 1, '-') OUTPUT, 
                cte.LEVEL + 1                       AS LEVEL 
         FROM   MASTER..spt_values v, 
                cte 
         WHERE  TYPE = 'P' 
                AND cte.LEVEL + 1 < Len(@input) 
                AND NUMBER BETWEEN 1 AND Len(@input)) SELECT DISTINCT OUTPUT 
FROM   cte 
UNION 
SELECT @INPUT 
ORDER  BY OUTPUT 
Run Code Online (Sandbox Code Playgroud)

产生以下输出

---    
--l    
-q-    
-ql    
s--    
s-l    
sq-    
sql
Run Code Online (Sandbox Code Playgroud)

我留给你一个功能.

看到它在这个data.se查询中工作