Как я уже упоминал в своем комментарии, если это единственные столбцы, которые у вас есть, то, что вы ищете, не достижимо.Без какого-то восходящего уникального ключа у вас нет возможности определить отношения.Если мы делаем и добавляем уникальный восходящий ключ, тогда мы можем достичь этого.
Если вы использовали SQL Server 2012+ (выпуск 2008поддержки, и очень близко к концу расширенной поддержки, поэтому обновление должно быть очень высоким приоритетом прямо сейчас), тогда вы можете создать свои острова, используя ROWS BETWEEN
, а затем использовать LEAD
:
CREATE TABLE dbo.SampleTable (ID int IDENTITY(1,1),
[system] varchar(8),
OrderNo int);
INSERT INTO dbo.SampleTable([System],OrderNo)
VALUES('system1',1),
('system2',2),
('system3',3),
('system4',4),
('system1',1),
('system2',2),
('system5',1),
('system6',2),
('system7',1),
('system8',2);
GO
WITH Groups AS(
SELECT ID,
[System],
COUNT(CASE WHEN OrderNo = 1 THEN 1 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM dbo.SampleTable)
SELECT [System] AS Parent,
LEAD([System]) OVER (PARTITION BY Grp ORDER BY ID) AS Child
FROM Groups;
GO
Без доступа к LEAD
и ROWS BETWEEN
вам придется быть более креативным;и решение будет гораздо медленнее:
WITH Groups AS(
SELECT ST.ID,
ST.[System],
G.Grp
FROM dbo.SampleTable ST
CROSS APPLY (SELECT COUNT(*) AS Grp
FROM dbo.SampleTable CA
WHERE CA.OrderNo =1
AND CA.ID <= ST.ID) G)
SELECT G1.[System] AS Parent,
G2.[System] AS Child
FROM Groups G1
LEFT JOIN Groups G2 ON G1.Grp = G2.Grp
AND G1.ID = G2.ID - 1;