原谅糟糕的头衔,但我找不到用抽象的术语表达我想要的东西的好方法。
无论如何我有3张桌子
tbl_product:
PID | productname
1 | product 1
2 | product 2
3 | product 3
4 | product 4
..
tbl_categories,motherCategory
允许我嵌套类别:
CID | categoriename | motherCategory
1 | electronics | NULL
2 | clothing | NULL
3 | Arduino | 1
4 | Casings, extra's | 3
..
tbl_productInCategory PID和CID分别是tbl_product和tbl_categories中PID和CID的外键。产品可以分配多个类别,因此PID可以在此表中多次出现。
PID | CID
1 | 1
2 | 1
3 | 3
4 | 4
现在我有一个查询,如果我给出mothercategory,则返回所有类别。 我想要做的是只显示递归中包含产品的类别。
例如上面的示例数据我显示所有类别(motherCategory为null),我希望它只返回电子产品,因为没有产品类别2,衣服。
然而,我遇到的问题是我还希望这个递归工作。考虑一下这个tbl_productInCategory:
PID | CID
1 | 2
2 | 2
3 | 2
4 | 4
现在它应该返回服装和电子产品,即使电子产品中没有产品,因为有嵌套类别的产品arduino->外壳,外壳。如果我用motherCategory显示所有类别,电子产品它也应该返回arduino。
我无法弄清楚如何做到这一点,任何帮助或指针都表示赞赏。
答案 0 :(得分:3)
首先,您应该选择存在产品的所有类别。在接下来的步骤中选择母类别。
WITH CTE AS
(
SELECT tbl_categories.*
FROM
tbl_categories
JOIN tbl_productInCategory on tbl_productInCategory.CID = tbl_categories.CID
UNION ALL
SELECT tbl_categories.*
FROM tbl_categories
JOIN CTE on tbl_categories.CID = CTE.motherCategory
)
SELECT DISTINCT * FROM CTE
答案 1 :(得分:0)
使用递归CTE获取类别树的派生表,然后将其连接到您的ProductCategory表。
答案 2 :(得分:0)
这不是我以前做过的事情,但是一些谷歌搜索表明它是可能的。
https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
递归执行的语义如下: 将CTE表达式拆分为锚点和递归成员。 运行创建第一个调用或基本结果集(T0)的锚成员。 以Ti作为输入并以Ti + 1作为输出运行递归成员。 重复步骤3,直到返回空集。 返回结果集。这是T0到Tn的UNION ALL。
USE AdventureWorks2008R2;
GO
WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
AS
(
-- Anchor member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
0 AS Level
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
WHERE ManagerID IS NULL
UNION ALL
-- Recursive member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
Level + 1
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.ManagerID = d.EmployeeID
)
-- Statement that executes the CTE
SELECT ManagerID, EmployeeID, Title, DeptID, Level
FROM DirectReports
INNER JOIN HumanResources.Department AS dp
ON DirectReports.DeptID = dp.DepartmentID
WHERE dp.GroupName = N'Sales and Marketing' OR Level = 0;
GO