ОК, вот что я пытаюсь сделать. Я использую запрос CTE в MSSQL2005. Цель запроса состоит в том, чтобы реорганизовать дочерние отношения с родителями по категориям продуктов и вернуть количество продуктов под каждую категорию (включая любые продукты, содержащиеся в детских категориях).Рекурсивный запрос с использованием CTE в SQL Server 2005
Моя текущая версия возвращает только количество товаров для категории отображается. Это не учет продуктов, которые могут содержаться в любом из его детей.
Свалка базы данных, чтобы воспроизвести проблему, наряду с запросом я использовал и объяснение следует ниже:
CREATE TABLE [Categories] (
[CategoryID] INT,
[Name] NCHAR(150)
)
GO
/* Data for the `Query_Result` table (Records 1 - 5) */
INSERT INTO [Categories] ([CategoryID], [Name])
VALUES (942, N'Diagnostic Equipment')
GO
INSERT INTO [Categories] ([CategoryID], [Name])
VALUES (943, N'Cardiology')
GO
INSERT INTO [Categories] ([CategoryID], [Name])
VALUES (959, N'Electrodes')
GO
INSERT INTO [Categories] ([CategoryID], [Name])
VALUES (960, N'Stress Systems')
GO
INSERT INTO [Categories] ([CategoryID], [Name])
VALUES (961, N'EKG Machines')
GO
CREATE TABLE [Categories_XREF] (
[CatXRefID] INT,
[CategoryID] INT,
[ParentID] INT
)
GO
/* Data for the `Query_Result` table (Records 1 - 5) */
INSERT INTO [Categories_XREF] ([CatXRefID], [CategoryID], [ParentID])
VALUES (827, 942, 0)
GO
INSERT INTO [Categories_XREF] ([CatXRefID], [CategoryID], [ParentID])
VALUES (828, 943, 942)
GO
INSERT INTO [Categories_XREF] ([CatXRefID], [CategoryID], [ParentID])
VALUES (928, 959, 943)
GO
INSERT INTO [Categories_XREF] ([CatXRefID], [CategoryID], [ParentID])
VALUES (929, 960, 943)
GO
INSERT INTO [Categories_XREF] ([CatXRefID], [CategoryID], [ParentID])
VALUES (930, 961, 943)
GO
CREATE TABLE [Products_Categories_XREF] (
[ID] INT,
[ProductID] INT,
[CategoryID] INT
)
GO
/* Data for the `Query_Result` table (Records 1 - 13) */
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252065, 12684, 961)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252066, 12685, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252067, 12686, 960)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252068, 12687, 961)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252128, 12738, 961)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252129, 12739, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252130, 12740, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252131, 12741, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252132, 12742, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252133, 12743, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252134, 12744, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252135, 12745, 959)
GO
INSERT INTO [Products_Categories_XREF] ([ID], [ProductID], [CategoryID])
VALUES (252136, 12746, 959)
GO
CREATE TABLE [Products] (
[ProductID] INT
)
GO
/* Data for the `Query_Result` table (Records 1 - 13) */
INSERT INTO [Products] ([ProductID])
VALUES (12684)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12685)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12686)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12687)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12738)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12739)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12740)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12741)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12742)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12743)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12744)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12745)
GO
INSERT INTO [Products] ([ProductID])
VALUES (12746)
GO
Вот запрос CTE я использовал:
WITH ProductCategories (CategoryID, ParentID, [Name], Level)
AS
(
-- Anchor member definition
SELECT
C.CategoryID,
CXR.ParentID,
C.Name,
0 AS Level
FROM
Categories C,
Categories_XRef CXR
WHERE
C.CategoryID = CXR.CategoryID
AND CXR.ParentID = 0
UNION ALL
-- Recursive member definition
SELECT
C.CategoryID,
CXR.ParentID,
C.Name,
Level + 1
FROM
Categories C,
Categories_XRef CXR,
ProductCategories AS PC
WHERE
C.CategoryID = CXR.CategoryID
AND CXR.ParentID = PC.CategoryID
)
SELECT
PC.ParentID,
PC.CategoryID,
PC.Name,
PC.Level,
(SELECT
Count(P.ProductID)
FROM
Products P,
Products_Categories_XREF PCXR
WHERE
P.ProductID = PCXR.ProductID
AND PCXR.CategoryID = PC.CategoryID
) as ProductCount
FROM
Categories C,
ProductCategories PC
WHERE
PC.CategoryID = C.CategoryID
AND PC.ParentID = 943
ORDER BY
Level, PC.Name
Во-первых, изменить " PC.ParentID "до 943. Вы увидите три возвращенные записи, показывающие количество товаров для каждой отображаемой категории.
Теперь измените ParentID от в и повторно запустить его. Теперь вы увидите 1 результат, получивший название «Кардиология», но он показывает 0 продуктов Под этой категорией есть дети (которые вы ранее видели), которые содержат продукты. Мой большой вопрос: на этом уровне (родительский 942), как я могу заставить его подсчитать продукты, содержащиеся в приведенных ниже дочерних элементах, чтобы показать 13 как «ProductCount». Я, как мне кажется, может потребоваться еще один метод рекурсии. Я пробовал это, но не имел успеха.
Я открыт для хранимой процедуры, которая будет делать то, что я ищу. Я не настроен определенным образом. Поэтому любые другие предложения будут оценены.
После сглаживания некоторых других ошибок этот фундаментальный остается: функции GROUP BY, HAVING или aggregate не разрешены в рекурсивной части рекурсивного общего выражения таблицы «ProductCategories» – Andomar
Andomar, я тоже получил эту ошибку, попробовав то же самое , По-видимому, вы не можете иметь ничего, кроме базовых выборок в рекурсивном запросе. – 2009-06-17 01:20:47
AakashM - это отлично работает, хотя вопрос заключается в том, как ограничить результаты запроса ко всему под 943? Добавление предложения where в качестве следующего ответа подсказывает, что он не совсем работает. – Marty