2011-12-21 28 views
7

Tôi cần một chức năng trong máy chủ sql để xây dựng tất cả các từ đã thay đổi trong ví dụ dưới đây; cho từ nhập liệu có độ dài n phải tạo từ 2^n thay đổi; Ví dụ, nếu đầu vào của hàm làlàm thế nào để xây dựng 2^n thay đổi từ từ với chiều dài n trong máy chủ sql

"I" 

đầu ra của hàm nên

I 
- 

đầu vào của hàm là

"am" 

đầu ra của hàm phải là

am 
-m 
a- 
-- 

đầu vào của hàm là

"sql" 

đầu ra của hàm nên

sql 
-ql 
s-l 
sq- 
--l 
s-- 
-q- 
--- 

Trả lời

9

Bạn có thể làm điều này với một số bảng (master..spt_values) và stuff trong một vòng lặp.

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 

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

Hoặc bạn có thể sử dụng một 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 

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

Cập nhật

Phiên bản CTE đệ quy là rất chậm như poi nted ra bởi OP trong một bình luận. Sử dụng một từ có 7 chữ cái có 960800 hàng được trả lại từ CTE.

+0

1 Và bạn có đầu ra theo thứ tự mà OP muốn –

+0

@ConradFrix - Trình tự là không cố ý :). –

+2

câu trả lời thứ hai là tốt nhưng thời gian cho chuỗi đầu vào "ví dụ" là 28 giây, câu trả lời đầu tiên rất tốt và thời gian cho chuỗi "example" là 0 giây – jozi

6

Recursive này 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 

xuất ra như sau

---  
--l  
-q-  
-ql  
s--  
s-l  
sq-  
sql 

tôi để lại nó cho bạn để đưa vào một hàm.

Xem nó làm việc tại đây data.se query

+0

Tôi cũng phải +1 điều này :) –

+0

của nó rất tốt nhưng đối với chuỗi đầu vào "ví dụ" 35 giây là thời gian chạy – jozi

Các vấn đề liên quan