关于php:自引用表和递归SQL函数

Self referential table and recursive SQL function

我有一个分类表:

  • 类别ID
  • 父类别ID
  • 类别名称

以及项目表:

  • 项目
  • 类别ID
  • 项目名称

我正在使用MySQL。我想编写一个查询,该查询将返回给定CategoryID的类别中的项目计数。查询应返回给定类别的所有子类别中所有项目的总计数。

我希望这是有道理的……对不起,如果我没有使用正确的命名法。


你对那个模式有多执着?它被称为"邻接表",从概念上讲,它足够简单,但它有一些真正的缺点。其中最重要的是无法查询所有后代。

看看这个,考虑一下表示树的另一种方法是否对您更好:

http://pugs.postgresql.org/files/modelingtrees.pdf


如果您正在考虑Jeff Dege引用的文档中描述的其他方法,请使用当前的邻接列表树结构:

对于经常读取但很少更改的数据,嵌套集速度非常快(读取使用SQL BETWEEN和索引;更改可能很昂贵,因为它们可能需要更新许多现有记录),而路径枚举(也称为物化路径)在使用索引和LIKE '[path]%'查询时提供了可接受的良好读取性能(至少据我所知,对于MySQL)和插入操作的良好性能,以及将类别移动到其他类别时可接受的性能。

我个人有一个项目,我使用路径枚举,其中数据库ID作为路径元素,点.分隔元素(例如祖先路径1.2.3.)。

您可能希望执行自己的基准来比较这些方法,特别是如果您有许多类别(几千个或更多)。


如果,如您所说,只有两个级别的类别,那么一个简单的连接/别名查询就可以正常工作。如果您允许任意深度,那么您就必须使用花哨的递归查询或邻接集,等等。

假设您只允许将项目附加到"较低"类别中,那么类似这样的内容将为您提供所需的结果:

1
2
3
4
5
6
7
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子句。


当然有可能,但效率不是很高。您应该使用嵌套集结构:http://intelligent enterprise.informationweek.com/001020/celko1_1.jhtml;jsessionid=afuxe0zf4ptnxqe1ghpsk4atmy32jvn

如果你不喜欢,请看这里:看看这个:http://explainextended.com/2010/04/18/hierarchy-query-in-mysql-limiting-parents/