Were you ever asked to generate string Permutations using TSql? I was recently asked to do so, and the logic which I could manage to come up at that point is shared in the below script.
DECLARE @Value AS VARCHAR(20) = 'ABCC' --Mention the text which is to be permuted
DECLARE @NoOfChars AS INT = LEN(@Value)
DECLARE @Permutations TABLE(Value VARCHAR(20)) --Make sure the size of this Value is equal to your input string length (@Value)
;WITH NumTally AS (--Prepare the Tally Table to separate each character of the Value.
SELECT 1 NumUNION ALL
SELECT Num + 1
FROM NumTally
WHERE Num < @NoOfChars
),Chars AS ( --Separate the CharactersSELECTNum,
SUBSTRING(@Value,Num,1) Chr
FROMNumTally
)
--Persist the Separated characters.
INSERT INTO @PermutationsSELECT Chr FROM Chars
--Prepare PermutationsDECLARE @i AS INT = 1
WHILE(@i < @NoOfChars)BEGIN--Store the Permutations
INSERT INTO @PermutationsSELECT DISTINCT --Add DISTINCT if required else duplicate Permutations will be generated for Repeated Chars.
P1.Value + P2.Value
FROM (SELECT Value FROM @Permutations WHERE LEN(Value) = @i) P1
CROSS JOIN
(SELECT Value FROM @Permutations WHERE LEN(Value) = 1) P2
--Increment the Counter.
SET @i += 1 --Delete the Incorrect Lengthed Permutations to keep the table size under control.
DELETE FROM @Permutations WHERE LEN(Value) NOT IN (1,@i)
END--Delete InCorrect Permutations.SET @i = 1WHILE(@i <= @NoOfChars)BEGIN--Deleting Permutations which has not used "All the Chars of the given Value".
DELETE FROM @Permutations
WHEREValue NOT LIKE '%' + SUBSTRING(@Value,@i,1) +'%'
--Deleting Permutations which have repeated incorrect character. DELETE FROM @Permutations
WHERELEN(Value) - LEN(REPLACE(Value,SUBSTRING(@Value,@i,1),'')) !=
LEN(@Value) - LEN(REPLACE(@Value,SUBSTRING(@Value,@i,1),''))
SET @i += 1 END--Selecting the generated Permutations.
SELECT Value FROM @Permutations
Hope, this script helps!
Please share your suggestions if you have any to improve this logic.
You are going to hit a MAXRECURSION limit at 100 permutations (the default)
ReplyDeleteHi Marc,
DeleteYes, you are correct in identifying the MAXRECURSION issue. However, that could be managed using the OPTION (MAXRECURSION X) with the query. Further details could be found at - http://vinay.inkeysolutions.com/2011/06/maximum-recursion-possible-with-cte-in.html
However, I would not suggest to generate PERMUTATIONS in SQL for long strings.
Please share your views for the same.