我今天面临的挑战是:如何从输入表中获得所需的输出表:
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)都是替代品:
B替换了A,E替换了A,所以B不仅替换了A,还替换了E,依此类推。 但是X和Z只能互相替代-它们都与其他元素无关。
最后,我想列出所有零件及其可能的替代物。
我对此表示感谢。
答案 0 :(得分:0)
双前锋
然后向后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