#sql-server
#sql-сервер
Вопрос:
Я ищу способ группировать связанные записи. Таблица, с которой я работаю, содержит уникальные пары идентификаторов. Связанные записи — это записи, в которых один из идентификаторов равен тому же идентификатору в другой записи.
Например, если запись содержит 384 и 768 для ID1 и ID2, то другая запись с 384 и 512 для ID1 и ID2 будет связана. Кроме того, другая запись с 256 и 768 также будет связана. Однако записи с 1024 и 1536 не будут связаны.
Пример таблицы и данных приведен ниже.
CREATE TABLE [dbo].[Identities](
[AN] [varchar](30) NOT NULL,
[ID1] [varchar](30) NOT NULL,
[ID2] [varchar](30) NULL,
[LastUpdateDate] [datetimeoffset](7) NOT NULL,
CONSTRAINT [PK_Identities] PRIMARY KEY CLUSTERED
(
[AN] ASC
) ON [PRIMARY],
CONSTRAINT [AK_ID] UNIQUE NONCLUSTERED
(
[ID1] ASC,
[ID2] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO [dbo].[Identities] ([AN], [ID1], [ID2], [LastUpdateDate])
VALUES
('00243', '6000086', '2200720', '2016-05-26 17:16:07.0000000 -04:00')
, ('00267', '6000752', '5700243', '2017-06-21 12:24:55.0000000 -04:00')
, ('00284', '6000086', '5000385', '2020-02-11 11:56:01.0000000 -05:00')
, ('00352', '6000752', '2200720', '2016-05-31 20:08:47.0000000 -04:00')
, ('00360', '6000752', '6000779', '2019-04-17 20:46:15.0000000 -04:00')
, ('00475', '6200598', '5000385', '2017-06-21 18:29:49.0000000 -04:00')
, ('00507', '6200599', '5000385', '2017-06-21 18:37:21.0000000 -04:00')
, ('00558', '6200606', '5000385', '2017-06-21 18:14:51.0000000 -04:00')
, ('00735', '5500045', '2200721', '2018-10-11 15:30:50.0000000 -04:00')
GO
Из этого примера данных желаемый результат приведен ниже.
AN ID1 ID2 LastUpdateDate Group
00243 6000086 2200720 2016-05-26 17:16:07.0000000 -04:00 1
00267 6000752 5700243 2017-06-21 12:24:55.0000000 -04:00 1
00284 6000086 5000385 2020-02-11 11:56:01.0000000 -05:00 1
00352 6000752 2200720 2016-05-31 20:08:47.0000000 -04:00 1
00360 6000752 6000779 2019-04-17 20:46:15.0000000 -04:00 1
00475 6200598 5000385 2017-06-21 18:29:49.0000000 -04:00 1
00507 6200599 5000385 2017-06-21 18:37:21.0000000 -04:00 1
00558 6200606 5000385 2017-06-21 18:14:51.0000000 -04:00 1
00735 5500045 2200721 2018-10-11 15:30:50.0000000 -04:00 2
Я считаю, что этого можно достичь с помощью рекурсивного запроса. Возможно, что-то похожее на решение здесь:рекурсивный запрос групп строк, но мои попытки оказались безуспешными.
Ответ №1:
Я думаю, вам нужно 2 рекурсивных cte, потому что ссылки должны идти в 2 направлениях. Что-то вроде этого:
WITH cte AS--recursive cte id2
(SELECT i1.ID1, i1.ID2
FROM [dbo].[Identities] i1
UNION ALL
SELECT c.ID1,i2.ID1
FROM [dbo].[Identities] i2
JOIN cte c ON c.ID2 = i2.ID2
) ,
cte2 AS--recursive cte id1
(SELECT i1.ID1, i1.ID2
FROM [dbo].[Identities] i1
UNION ALL
SELECT c.ID2, i2.ID2
FROM [dbo].[Identities] i2
JOIN cte c ON c.ID1 = i2.ID1
) ,
cte3 AS--union both recursive cte's
(SELECT *
FROM cte
UNION
SELECT *
FROM cte2
),
cte4 AS--group
(SELECT id1, min(id2) AS id2, dense_rank() OVER (ORDER BY min(id2)) AS grp
FROM cte3
GROUP BY id1)
SELECT i.AN,i.ID1,i.ID2,i.LastUpdateDate,c.grp
FROM cte4 c
JOIN [dbo].[Identities] i ON i.id1 = c.id1