行相互链接INTO列

时间:2019-02-01 13:20:00

标签: sql tsql

enter image description here

我今天面临的挑战是:如何从输入表中获得所需的输出表:

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只能互相替代-它们都与其他元素无关。

最后,我想列出所有零件及其可能的替代物。

我对此表示感谢。

1 个答案:

答案 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