我有一个类别表:
- 类别ID
- 父类别 ID
- 分类名称
和一个项目表:
- 物品编号
- 类别ID
- 项目名
我正在使用 MySQL。我想编写一个查询,该查询将返回给定类别 ID 的类别中的项目计数。该查询应返回给定类别的所有子类别中的所有项目的总数。
我希望这是有道理的..对不起,如果我没有使用正确的命名法。
我有一个类别表:
和一个项目表:
我正在使用 MySQL。我想编写一个查询,该查询将返回给定类别 ID 的类别中的项目计数。该查询应返回给定类别的所有子类别中的所有项目的总数。
我希望这是有道理的..对不起,如果我没有使用正确的命名法。
您在该模式上的坚持程度如何?它被称为“邻接表”,从概念上讲它很简单,但它有一些真正的缺点。其中最重要的是无法查询所有后代。
看看这个,并考虑另一种表示树的方法是否更适合您:
当然它是可能的,但不是很有效。你应该使用嵌套的集合结构: http://intelligent-enterprise.informationweek.com/001020/celko1_1.jhtml;jsessionid= AFUXE0ZF4PTNXQE1GHPSKH4ATMY32JVN
如果你不喜欢看这里:看看这个:http ://explainextended.com/2010/04/18/hierarchical-query-in-mysql-limiting-parents/
如果,如您所说,只有两个级别的类别,那么一个简单的连接/别名查询就可以正常工作。如果您允许任意深度,那么您将不得不使用花哨的递归查询或邻接集等等。
假设您只允许将项目附加到“较低”类别,那么类似的东西应该可以为您提供所需的结果:
SELECT top.categoryID, top.categoryName, bottom.categoryID, bottom.categoryName,
COUNT (items.itemID)
FROM categories AS top
LEFT JOIN categories AS bottom ON top.categoryID = bottom.parentCategoryID
LEFT JOIN items ON bottom.categoryID = items.categoryID
WHERE (bottom.categoryID = $your_category)
GROUP BY top.categoryID, bottom.categoryID
如果您只需要查看顶级类别,请WHERE
根据需要更改该子句。
如果您正在考虑Jeff Dege引用的文档中描述的替代方法,那么您当前的邻接列表树结构:
嵌套集对于经常读取但很少更改的数据非常快(读取使用 SQLBETWEEN
和索引;更改可能很昂贵,因为它们可能必须更新许多现有记录),而路径枚举(也称为物化路径)提供了可接受的良好使用索引和LIKE '[path]%'
查询时的读取性能(据我所知至少对于 MySQL),插入操作的良好性能以及将类别移动到不同类别时的可接受性能。
我个人有一个项目,我使用带有数据库 ID 作为路径元素和一个点.
来分隔元素(例如祖先路径1.2.3.
)的路径枚举。
您可能希望进行自己的基准测试来比较这些方法,尤其是当您有很多类别(数千或更多)时。