仅显示其中包含产品的类别
show only categories that have products in them
请原谅这个糟糕的标题,但我找不到用抽象术语表达我想要的东西的好方法。
反正我有3个tables
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 可以在此 table.
中出现多次
PID | CID
1 | 1
2 | 1
3 | 3
4 | 4
现在我有一个查询,如果我给出母类别,return所有类别。
我想要做的是仅递归地显示其中包含产品的类别。
例如,在上面的示例数据中,我显示了所有类别(motherCategory 为空),我希望它 return 只有电子产品,因为没有产品类别 2,服装。
但是我遇到的问题是我也希望它递归工作。考虑这个 tbl_productInCategory:
PID | CID
1 | 2
2 | 2
3 | 2
4 | 4
现在它应该 return 服装和电子产品,即使电子产品中没有产品,因为嵌套类别 arduino->Casings,extra's 中有产品。如果我用 motherCategory 显示所有类别,电子产品也应该 return arduino。
我不知道该怎么做,感谢任何帮助或指点。
使用递归 CTE 获取类别树的派生 table,然后将其 INNER JOIN 到您的 ProductCategory table。
这不是我以前做过的事情,但谷歌搜索表明这是可能的。
https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
The semantics of the recursive execution is as follows:
Split the CTE expression into anchor and recursive members.
Run the anchor member(s) creating the first invocation or base result set (T0).
Run the recursive member(s) with Ti as an input and Ti+1 as an output.
Repeat step 3 until an empty set is returned.
Return the result set. This is a UNION ALL of T0 to Tn.
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
首先,您应该 select 所有存在产品的类别。关于后续步骤select母类。
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
请原谅这个糟糕的标题,但我找不到用抽象术语表达我想要的东西的好方法。
反正我有3个tables
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 可以在此 table.
中出现多次PID | CID
1 | 1
2 | 1
3 | 3
4 | 4
现在我有一个查询,如果我给出母类别,return所有类别。 我想要做的是仅递归地显示其中包含产品的类别。
例如,在上面的示例数据中,我显示了所有类别(motherCategory 为空),我希望它 return 只有电子产品,因为没有产品类别 2,服装。
但是我遇到的问题是我也希望它递归工作。考虑这个 tbl_productInCategory:
PID | CID
1 | 2
2 | 2
3 | 2
4 | 4
现在它应该 return 服装和电子产品,即使电子产品中没有产品,因为嵌套类别 arduino->Casings,extra's 中有产品。如果我用 motherCategory 显示所有类别,电子产品也应该 return arduino。
我不知道该怎么做,感谢任何帮助或指点。
使用递归 CTE 获取类别树的派生 table,然后将其 INNER JOIN 到您的 ProductCategory table。
这不是我以前做过的事情,但谷歌搜索表明这是可能的。
https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
The semantics of the recursive execution is as follows: Split the CTE expression into anchor and recursive members. Run the anchor member(s) creating the first invocation or base result set (T0). Run the recursive member(s) with Ti as an input and Ti+1 as an output. Repeat step 3 until an empty set is returned. Return the result set. This is a UNION ALL of T0 to Tn.
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
首先,您应该 select 所有存在产品的类别。关于后续步骤select母类。
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