Рекурсивный CTE для поиска родительских записей
во-первых, я должен признать, что я не очень хорошо знаком с sql server рекурсивного CTE-х но я думаю, что это лучший подход.
у меня есть таблица tabData
. Его PK называется idData
и есть собственная ссылка FK fiData
.
таким образом, fiData ссылается на родительскую запись и SELECT * FROM tabData WHERE idData=fiData
возвращает все данные из родителей. Это просто и быстро. Но как получить всех родителей из данной записи в естественном порядке?
Говорят, есть один ребенок (idData=4) с 3 родителями (первый родитель-это запись с idData=3):
idData fiData
4 3
3 2
2 1
1 NULL
Я думал, что рекурсивный CTE-это путь, но я не очень хорошо справляюсь с его синтаксисом. Итак, каков правильный способ реализации CTE, который возвращает всех родителей?
Я пробовал следующие, но это дает мне неправильный результат(3,4 вместо 3,2,1): (Чтобы проверить это, я создал временную таблицу для меня и тебя)
IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'tabData_Temp'))
BEGIN
CREATE TABLE [dbo].[tabData_Temp](
[idData] [int] NOT NULL,
[fiData] [int] NULL,
CONSTRAINT [PK_tabData_Temp] PRIMARY KEY CLUSTERED
(
[idData] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
);
ALTER TABLE [dbo].[tabData_Temp] WITH CHECK ADD CONSTRAINT [FK_tabData_Temp] FOREIGN KEY([fiData])
REFERENCES [dbo].[tabData_Temp] ([idData]);
ALTER TABLE [dbo].[tabData_Temp] CHECK CONSTRAINT [FK_tabData_Temp];
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(1,NULL);
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(2,1);
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(3,2);
INSERT INTO [dbo].[tabData_Temp](idData,fiData)VALUES(4,3);
END
/* here comes the (not working) recursive CTE */
Declare @fiData int;
SET @fiData = 3;
WITH PreviousClaims(idData,fiData)
AS(
SELECT parent.idData,parent.fiData
FROM tabData_temp parent
WHERE parent.idData = @fiData
UNION ALL
SELECT child.idData,child.fiData
FROM tabData_temp child
INNER JOIN PreviousClaims parent ON parent.idData = child.fiData
)
SELECT idData
FROM PreviousClaims;
/* end of recursive CTE */
DROP TABLE [dbo].[tabData_Temp];
спасибо заранее.
2 ответов
изменения в:
INNER JOIN PreviousClaims parent ON parent.fiData = child.idData
дал мне результаты, которые вы хотели.
у вас есть соединение назад.
изменить это
INNER JOIN PreviousClaims parent ON parent.idData= child.fiData
этой
INNER JOIN PreviousClaims parent ON parent.fiData = child.idData