我今天充满挑战的挑战是:如何从输入表实现所需的输出表:
DECLARE @table1 TABLE
(
[Sub1] CHAR(1),
[Sub2] CHAR(1)
);
INSERT INTO @table1
VALUES
('A', 'B'),
('A', 'D'),
('A', 'F'),
('A', 'E'),
('A', 'A'),
('A', 'C'),
('A', 'G'),
('C', 'A'),
('B', 'A'),
('X', 'Z');
select * from @table1;
我们的想法是:所有元素(从A到G)是替代:
乙取代了A,E代替了所以B不仅是A,但é以及等取代。但是X和Z的替代只有对方 - 他们都没有连接元件的任何其他。
最后,我想有列出的所有部件和可能的替代品。
我将不胜感激的任何建议。
以一个双管正激,
然后TRIPPLE它倒退,
和枢轴各地!
(关于“Sing, sing, sing”曲调)
declare @DoubleSub table (
[Sub1] CHAR(1) NOT NULL,
[Sub2] CHAR(1) NOT NULL,
PRIMARY KEY ([Sub1], [Sub2])
);
INSERT INTO @DoubleSub ([Sub1], [Sub2])
SELECT [Sub1], [Sub2] FROM @table1
UNION
SELECT [Sub2], [Sub1] FROM @table1;
;WITH TRIPLESUB AS
(
SELECT [Sub1] as [Main], 1 as Lvl, [Sub1], [Sub2], CAST('|'+ [Sub1] +'|'+ [Sub2] +'|' AS VARCHAR(200)) as Visited
FROM @DoubleSub
UNION ALL
SELECT c.[Main], c.Lvl + 1, t.[Sub1], t.[Sub2],
CAST(c.Visited + t.[Sub2] + '|' AS VARCHAR(200))
FROM TRIPLESUB c
JOIN @DoubleSub t
ON t.[Sub1] = c.[Sub2]
AND c.Lvl < 12
AND c.[Main] != t.[Sub2]
AND c.Visited NOT LIKE CONCAT('%|',t.[Sub2],'|%')
)
SELECT
[Main],
[1] as [Substitute1],
[2] as [Substitute2],
[3] as [Substitute3],
[4] as [Substitute4],
[5] as [Substitute5],
[6] as [Substitute6]
FROM
(
SELECT [Main], [Sub2],
ROW_NUMBER() OVER (PARTITION BY [Main] ORDER BY IIF([Main]<[Sub2],0,1), [Sub2]) AS RN
FROM TRIPLESUB
WHERE [Main] != [Sub2]
GROUP BY [Main], [Sub2]
) AS src
PIVOT
(
MAX([Sub2])
FOR RN IN ([1],[2],[3],[4],[5],[6])
) AS pvt;
测试here
返回:
Main Substitute1 Substitute2 Substitute3 Substitute4 Substitute5 Substitute6
A B C D E F G
B C D E F G A
C D E F G A B
D E F G A B C
E F G A B C D
F G A B C D E
G A B C D E F
X Z NULL NULL NULL NULL NULL
Z X NULL NULL NULL NULL NULL