MAK*_*MAK 10 sql-server sql-server-2008-r2
我有以下用于排列和组合的示例数据。
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 ');
Run Code Online (Sandbox Code Playgroud)
我想为 中的name
列生成排列和组合table tbltest
并将其存储到temp table
.
以预期结果为例:
name
----------------
John Mak Sam
John Sam Mak
Mak John Sam
Mak Sam John
Sam John Mak
Sam Mak John
....
....
Run Code Online (Sandbox Code Playgroud)
尝试使用以下查询:源
注意:以下查询对单个记录按预期工作,但是当我尝试使用游标在表上运行时,它的运行时间超过 35 分钟,并且仍然保持运行。
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
Run Code Online (Sandbox Code Playgroud)
And*_*y M 15
如果将每个名称拆分为以下结构的单独表,
CREATE TABLE dbo.NameParts
(
ID int NOT NULL,
NamePart varchar(30) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
(其中ID
标记属于相同名称的名称部分,以避免不同名称部分的排列) – 然后您可以使用递归 CTE 来生成排列:
WITH
permutations AS
(
SELECT
ID = t.ID,
FullNameVariation = CAST(t.NamePart AS varchar(500)),
Level = COUNT(*) OVER (PARTITION BY t.ID)
FROM
dbo.NameParts AS t
UNION ALL
SELECT
ID = t.ID,
FullNameVariation = CAST(p.FullNameVariation + ' ' + t.NamePart AS varchar(500)),
Level = p.Level - 1
FROM
dbo.NameParts AS t
INNER JOIN permutations AS p ON t.ID = p.ID
WHERE 1=1
AND p.Level > 1
AND ' ' + p.FullNameVariation + ' ' NOT LIKE '% ' + t.NamePart + ' %'
)
SELECT
ID,
FullNameVariation
FROM
permutations
WHERE
Level = 1
ORDER BY
ID,
FullNameVariation
;
Run Code Online (Sandbox Code Playgroud)
将查询应用于此数据样本:
INSERT INTO dbo.NameParts
VALUES
(1, 'Sam'), (1, 'Mak'), (1, 'John'),
(2, 'Donatella'), (2, 'Nobatti'),
(3, 'Sam'), (3, 'Buca'),
(4, 'Juan'), (4, 'Soponatime'),
(5, 'Aaron'), (5, 'Spacemuseum')
;
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
CREATE TABLE dbo.NameParts
(
ID int NOT NULL,
NamePart varchar(30) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
您可以使用现场演示来使用此解决方案在db<>fiddle.uk。
归档时间: |
|
查看次数: |
2030 次 |
最近记录: |