MYSQL 通过在逗号分隔的字符串中查找其 ID 来查询以计算项目的后代
MYSQL query to count descendants of items by finding its id in a comma separated string
我的 MYSQL 数据库使用 tree-like 系统,其中每个项目都可以有任意数量的后代。每个项目都有一个包含其 parent 的常规 INT 'parent' 列以及一个 VARCHAR 'parents' 列,该列由包含其所有祖先 ID 的 comma-separated 字符串组成。
id parent parents
-------------------------------
1 0 0
2 1 0,1
3 1 0,1
4 3 0,1,3
我需要获取所有项目的列表,每个项目都计算了它们的后代总数。这是我到目前为止的查询:
SELECT items.id AS item_id,
COUNT(children.id) AS children
FROM items items
LEFT JOIN items children ON (items.id IN (children.parents))
这只会发回一行,child 计数为 0。我该如何正确执行此操作?
编辑:
修复查询后,它看起来像这样:
SELECT
i.id AS item_id,
COUNT(*) AS children
FROM
items i
LEFT JOIN
items c
ON (i.id IN (c.parents))
GROUP BY i.id;
结果显示行,但每行只有一个 child。这不反映数据,大概是 IN 语句有问题(FIND_IN_SET 做同样的事情)。
编辑 2:
IN语句改成如下后
ON LOCATE(i.id, c.parents) > 0
项目 1 的 children (3) 数正确,但其余项目均显示为 1 child。第 2 项和第 4 项应为 0,第 3 项应为 1。
您需要 GROUP BY items.id
才能 COUNT()
正常工作。
将别名更改为更明确的名称:
SELECT
i.id AS item_id,
COUNT(*) AS children
FROM
items i
LEFT JOIN
items c
ON FIND_IN_SET(i.id, c.parents) > 0
WHERE c.id <> i.id
GROUP BY i.id;
有关更复杂的 COUNT()/GROUP BY 示例,请参阅 this question or MySQL documentation. For FIND_IN_SET()
, nice example here。
参见 sqlfiddle here
我的 MYSQL 数据库使用 tree-like 系统,其中每个项目都可以有任意数量的后代。每个项目都有一个包含其 parent 的常规 INT 'parent' 列以及一个 VARCHAR 'parents' 列,该列由包含其所有祖先 ID 的 comma-separated 字符串组成。
id parent parents
-------------------------------
1 0 0
2 1 0,1
3 1 0,1
4 3 0,1,3
我需要获取所有项目的列表,每个项目都计算了它们的后代总数。这是我到目前为止的查询:
SELECT items.id AS item_id,
COUNT(children.id) AS children
FROM items items
LEFT JOIN items children ON (items.id IN (children.parents))
这只会发回一行,child 计数为 0。我该如何正确执行此操作?
编辑:
修复查询后,它看起来像这样:
SELECT
i.id AS item_id,
COUNT(*) AS children
FROM
items i
LEFT JOIN
items c
ON (i.id IN (c.parents))
GROUP BY i.id;
结果显示行,但每行只有一个 child。这不反映数据,大概是 IN 语句有问题(FIND_IN_SET 做同样的事情)。
编辑 2:
IN语句改成如下后
ON LOCATE(i.id, c.parents) > 0
项目 1 的 children (3) 数正确,但其余项目均显示为 1 child。第 2 项和第 4 项应为 0,第 3 项应为 1。
您需要 GROUP BY items.id
才能 COUNT()
正常工作。
将别名更改为更明确的名称:
SELECT
i.id AS item_id,
COUNT(*) AS children
FROM
items i
LEFT JOIN
items c
ON FIND_IN_SET(i.id, c.parents) > 0
WHERE c.id <> i.id
GROUP BY i.id;
有关更复杂的 COUNT()/GROUP BY 示例,请参阅 this question or MySQL documentation. For FIND_IN_SET()
, nice example here。
参见 sqlfiddle here