Ich habe die folgenden Beispieldaten für Permutationen und Kombinationen.
create table tbltest
(
name varchar(50),
addres varchar(100)
);
insert into tbltest values('Sam Mak John','Street 1 HNo 101 USA');
insert into tbltest values('Donatella Nobatti','HNo 101 UK');
insert into tbltest values('Sam Buca','Main Road B Block UAE');
insert into tbltest values('Juan Soponatime','Hight Street CA');
insert into tbltest values('Aaron Spacemuseum','HNo A10 100 feet Road A Block ');
Ich möchte Permutationen und Kombinationen für die name
Spalte in der table tbltest
und in speichern temp table
.
Für ein Beispiel erwartetes Ergebnis:
name
----------------
John Mak Sam
John Sam Mak
Mak John Sam
Mak Sam John
Sam John Mak
Sam Mak John
....
....
Versucht mit folgender Abfrage: Quelle
Hinweis: Die folgende Abfrage funktioniert wie erwartet für einen einzelnen Datensatz, aber wenn ich die Tabelle mit dem Cursor ausprobiert habe, läuft sie länger als 35 Minuten und läuft weiter.
DECLARE @inputStr VARCHAR(MAX)= 'Sam Mak John';
DECLARE @ValueStr VARCHAR(100);
DECLARE @Count INT, @Loop INT= 1, @totalSum INT;
DECLARE @Query1 VARCHAR(1000), @Query2 VARCHAR(1000), @Query3 VARCHAR(1000), @Query4 VARCHAR(1000), @Query5 VARCHAR(1000), @Query6 VARCHAR(1000), @Query VARCHAR(4000), @Combination VARCHAR(1000);
--Temporary table to capture all the words separately
CREATE TABLE #tmpvalues
(intIndex INT IDENTITY(1, 1),
intProc INT,
subStr VARCHAR(100)
);
--Temporary table to store all the possible combinations
CREATE TABLE #tmpCombinations
(subCombStr VARCHAR(1000)
);
--get the sub-strings(words) from input statement into a temp table
WHILE LEN(@inputStr) > 0
BEGIN
SET @ValueStr = LEFT(@inputStr, ISNULL(NULLIF(CHARINDEX(' ', @inputStr) - 1, -1), LEN(@inputStr)));
SET @inputStr = SUBSTRING(@inputStr, ISNULL(NULLIF(CHARINDEX(' ', @inputStr), 0), LEN(@inputStr)) + 1, LEN(@inputStr));
INSERT INTO #tmpvalues
VALUES
(@Loop,
@ValueStr
);
SET @Loop = @Loop + 1;
END;
SELECT @Count = MAX(intINDEX)
FROM #tmpvalues;
SET @Loop = 1;
--Set an integer values for each words
--This will be used to filter the combinations in which any two words are repating
DECLARE @tempIntAdd INT;--Addition factor
SET @tempIntAdd = @Loop * @Count;
WHILE @Loop <= (@Count - 1)
BEGIN
DECLARE @tempIntProc INT;
SELECT @tempIntProc = intProc
FROM #tmpvalues
WHERE intIndex = @Loop;
UPDATE #tmpvalues
SET
intProc = @tempIntProc + @tempIntAdd
WHERE intIndex = @Loop + 1;
SET @Loop = @Loop + 1;
SET @tempIntAdd = @tempIntAdd * 2;
END;
--
SET @Loop = 1;
SET @Query1 = 'INSERT INTO #tmpCombinations SELECT DISTINCT ';
SET @Query2 = 'ALL_COMBINATIONS FROM';
SET @Query3 = ' ';
SET @Query4 = ' WHERE';
SET @Query5 = '(';
SET @Query6 = ')';
-- Generate the dynamic query to get permutations and combination of individual words
WHILE @Loop <= @Count
BEGIN
SELECT @ValueStr = subStr
FROM #tmpvalues
WHERE intIndex = @Loop;
SET @Query1 = @Query1 + 'T' + CAST(@Loop AS VARCHAR) + '.subStr ';
IF(@Loop < @Count)
SET @Query1 = @Query1 + '+ '' '' + ';
SET @Query3 = @Query3 + '#tmpvalues ' + 'T' + CAST(@Loop AS VARCHAR);
IF(@Loop < @Count)
SET @Query3 = @Query3 + ', ';
SET @Query5 = @Query5 + 'T' + CAST(@Loop AS VARCHAR) + '.intProc';
IF(@Loop < @Count)
SET @Query5 = @Query5 + ' + ';
SET @Loop = @Loop + 1;
END;
SELECT @totalSum = SUM(intProc)
FROM #tmpvalues;
--Create final query
SET @Query = @Query1 + @Query2 + @Query3 + @Query4 + @Query5 + @Query6 + ' =' + CAST(@totalSum AS VARCHAR);
--Execute the dynamic Query
EXECUTE (@Query);
SELECT subCombStr from #tmpCombinations
Antworten:
Wenn Sie jeden Namen in eine separate Tabelle mit der folgenden Struktur aufteilen,
(wo
ID
Markierungen Namensteile markieren, die zum selben Namen gehören, um die Permutation von Teilen mit unterschiedlichen Namen zu vermeiden) - dann können Sie einen rekursiven CTE verwenden, um die Permutationen zu erzeugen:Anwenden der Abfrage auf dieses Datenbeispiel:
erzeugt die folgende Ausgabe:
Sie können mit dieser Lösung mithilfe einer Live-Demo auf db <> fiddle.uk spielen.
quelle