自引用表和递归SQL函数

时间:2010-09-14 21:38:56

标签: php mysql self-reference

我有一个类别表:

  • 的categoryID
  • parentCategoryID
  • 类别名称

和一个项目表:

  • ITEMID
  • 的categoryID
  • ITEMNAME

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

我希望这是有道理的...抱歉,如果我没有使用正确的命名法。

4 个答案:

答案 0 :(得分:2)

你对这个架构有多困难?它被称为“邻接列表”,从概念上来说它很简单,但它有一些真正的缺点。其中最重要的是无法查询所有后代。

看看这个,并考虑一种表示树木的替代方法是否可能更适合您:

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

答案 1 :(得分:0)

答案 2 :(得分:0)

如果你说只有两个级别的类别,那么一个简单的连接/别名查询就可以了。如果你允许任意深度,那么你必须使用花哨的递归查询或邻接集以及诸如此类的东西。

假设您只允许将项目附加到“较低”类别,那么应该可以获得您需要的结果:

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子句。

答案 3 :(得分:0)

如果您正在考虑document引用的Jeff Dege所描述的替代方法,请使用当前的邻接列表树结构:

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

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

您可能希望使用自己的基准来比较这些方法,特别是如果您有很多类别(数千或更多)。