MAK*_*MAK 4 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 ');
insert into tbltest values('Nasir Ahmed Amir Ahmed Mehendy','UAE High Street');
Run Code Online (Sandbox Code Playgroud)
以预期结果为例:
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)
尝试了上一个问题的解决方案:
--To store Words
CREATE TABLE dbo.NameParts
(
ID int NOT NULL,
NamePart varchar(30) NOT NULL
);
--Table variable to identity column for each words
DECLARE @Inter TABLE (id int identity(1,1), names varchar(max));
--Insert into table variable
INSERT INTO @Inter(names) SELECT name from TblTest;
--Query to insert into NameParts table
;WITH splitdata
AS
(
SELECT id,splitname
FROM
(
SELECT *,Cast('<X>' + Replace(F.Names, ' ', '</X><X>') + '</X>' AS XML) AS xmlfilter
FROM @Inter F
)F1
CROSS apply
(
SELECT fdata.d.value('.', 'varchar(50)') AS splitName
FROM f1.xmlfilter.nodes('X') AS fdata(d)
) O
)
INSERT INTO dbo.NameParts
SELECT *
FROM splitdata;
Run Code Online (Sandbox Code Playgroud)
排列组合查询:
--Query for Permutation and Combination
;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
OPTION (MAXRECURSION 5100);
Run Code Online (Sandbox Code Playgroud)
注意:上述查询工作正常,但无法在结果集中获得以下记录:
Nasir Ahmed Amir Ahmed Mehendy
那是因为这个条件:
' ' + p.FullNameVariation + ' ' NOT LIKE '% ' + t.NamePart + ' %'
Run Code Online (Sandbox Code Playgroud)
单词Ahmed重复,不满足上述条件。
Geo*_*ios 10
扩展Andriy M的原始答案,我们可以在插入阶段使用虚拟字符(在我的情况下我使用 ~)统一字符串,然后删除该字符。
在这种情况下,我选择使用 REPLICATE 传递虚拟字符 '~' 和 ROW_NUMBER 函数作为要复制的实例数。这应该确保所有字符串都是唯一的。
完整代码
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 ');
insert into tbltest values('Nasir Ahmed Amir Ahmed Mehendy','UAE High Street');
GO
CREATE TABLE dbo.NameParts
(
ID int NOT NULL,
NamePart varchar(30) NOT NULL
);
--Table variable to identity column for each words
DECLARE @Inter TABLE (id int identity(1,1), names varchar(max));
--Insert into table variable
INSERT INTO @Inter(names) SELECT name from TblTest;
--Query to insert into NameParts table
;WITH splitdata
AS
(
SELECT id,splitname
FROM
(
SELECT *,Cast('<X>' + Replace(F.Names, ' ', '</X><X>') + '</X>' AS XML) AS xmlfilter
FROM @Inter F
)F1
CROSS apply
(
SELECT fdata.d.value('.', 'varchar(50)') AS splitName
FROM f1.xmlfilter.nodes('X') AS fdata(d)
) O
)
INSERT INTO dbo.NameParts
SELECT id,[splitdata].[splitName] + REPLICATE('~',(ROW_NUMBER() OVER (PARTITION BY [splitdata].[id] ORDER BY [splitdata].[splitName] ASC))
FROM splitdata;
GO
;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,
REPLACE(FullNameVariation,'~','')
FROM
permutations
WHERE 1=1 AND
Level = 1
ORDER BY
ID,
FullNameVariation
OPTION (MAXRECURSION 5100);
DROP TABLE [dbo].[tbltest]
DROP TABLE [dbo].[NameParts]
Run Code Online (Sandbox Code Playgroud)