我如何 select 所有条目在 MySQL 中没有 child
How can I select all entries without a child in MySQL
table有以下列
CODE VARCHAR(255)
-> class 的代码(不唯一)(例如 test 或 test2)
FULLPATH VARCHAR(255)
-> 包含所有 parent class 代码的完整路径(唯一)(例如 test-test2)
NAME VARCHAR(255)
-> 打印名称(例如01.Test2)
PARENT VARCHAR(255)
-> 可选 parent 代码(可以为空)(例如测试)
我现在想要达到的是 SELECT
所有 children 的计数 children (所以在树中的叶子)
我已经找到一个 SELECT
来获取所有 children
SELECT a.*, (COUNT(c.CODE)-1) as 'ChildCount'
FROM dir_asset_class AS a
LEFT JOIN dir_asset_class AS c ON LOCATE(a.CODE, c.FULLPATH) > 0
WHERE a.PARENT IS NULL
GROUP BY a.CODE
ORDER BY a.NAME ASC
本returns全部children无顶parent。
我现在尝试获取所有 Children 没有 children 的子选择,看起来像这样:
SELECT dac.CODE, dac.FULLPATH
FROM dir_asset_class as dac2
LEFT JOIN dir_asset_class as dac on locate(dac.CODE, dac2.FULLPATH) > 0
GROUP BY dac.CODE
HAVING (COUNT(dac.FULLPATH)-1) = 0
它工作了一半...它给了我一些 children 没有任何进一步的 children。但是很多都不见了。
有没有办法在没有程序的情况下解决这个问题(所以只有子选择?)
如果需要更多信息,请告诉我。
编辑:Link 到 SQLFiddle:http://sqlfiddle.com/#!9/cd8ff
试试这个 sqlfiddle
-- get all children that have no child, bottommost children
SELECT c1.*
FROM dir_asset_class as c1
LEFT JOIN dir_asset_class as c2
ON c1.code != c2.code
AND ( c2.FULLPATH like CONCAT(c1.code,'-%')
OR c2.FULLPATH like CONCAT('%-',c1.code,'-%')
OR c2.FULLPATH like CONCAT('%-',c1.code)
)
WHERE c2.code IS NULL
这里还有 sql 来计算根的所有子节点(父行为空的行)而无需 -1
-- get count of all children including grandchild of codes that have no parent
SELECT a.*,COUNT(c.CODE) as 'ChildCount'
FROM dir_asset_class as a
INNER JOIN dir_asset_class as c -- ON LOCATE(a.CODE, c.FULLPATH) > 0
ON c.FULLPATH like CONCAT(a.CODE,'-%')
WHERE a.PARENT IS NULL
AND a.code != c.code
GROUP BY a.CODE
ORDER BY a.NAME ASC;
更新:如果 FULLPATH 是唯一的并且 PARENT 引用它..我们可以使用
this sqlfiddle
SELECT c1.*
FROM dir_asset_class as c1
LEFT JOIN dir_asset_class as c2 ON c1.FULLPATH = c2.parent
WHERE c2.code IS NULL
and c1.parent IS NOT NULL
好的,这是我的看法:
SELECT * FROM `dir_asset_class` WHERE `CODE` NOT IN
(SELECT RIGHT(`PARENT`, LOCATE("-", RPAD(REVERSE(`PARENT`), 255, "-")) - 1)
FROM `dir_asset_class` WHERE PARENT IS NOT NULL ) ;
想法是获取所有未出现在 parent
值中的元素。为此,我们必须提取 parent
"tree" 的所有最后一项,这是通过子查询中的棘手事情完成的。我添加了一个 -
和 RPAD
以确保 parent
字符串中至少有一个 -
,否则它会导致树的顶部出现问题(s).
Returns :
+--------+-------------------------------+------------+------------------------+
| CODE | FULLPATH | NAME | PARENT |
+--------+-------------------------------+------------+------------------------+
| test3 | TEST-test2-test3 | 01. Test3 | TEST-test2 |
| test61 | TEST-test2-test4-test6-test61 | 01. Test61 | TEST-test2-test4-test6 |
| test62 | TEST-test2-test4-test6-test62 | 02. Test62 | TEST-test2-test4-test6 |
| test63 | TEST-test2-test4-test6-test63 | 03. Test63 | TEST-test2-test4-test6 |
| test5 | TEST-test5 | 02. Test5 | TEST |
| other | TEST-test7-other | 03. Other | TEST-test7 |
| test71 | TEST-test7-test71 | 01. Test71 | TEST-test7 |
| test72 | TEST-test7-test72 | 02. Test72 | TEST-test7 |
| other | Test10-other | 01. Other | Test10 |
| test9 | test8-test9 | 01. Test9 | test8 |
+--------+-------------------------------+------------+------------------------+
10 rows in set (0.00 sec)
这似乎是对的。
table有以下列
CODE VARCHAR(255)
-> class 的代码(不唯一)(例如 test 或 test2)FULLPATH VARCHAR(255)
-> 包含所有 parent class 代码的完整路径(唯一)(例如 test-test2)NAME VARCHAR(255)
-> 打印名称(例如01.Test2)PARENT VARCHAR(255)
-> 可选 parent 代码(可以为空)(例如测试)
我现在想要达到的是 SELECT
所有 children 的计数 children (所以在树中的叶子)
我已经找到一个 SELECT
来获取所有 children
SELECT a.*, (COUNT(c.CODE)-1) as 'ChildCount'
FROM dir_asset_class AS a
LEFT JOIN dir_asset_class AS c ON LOCATE(a.CODE, c.FULLPATH) > 0
WHERE a.PARENT IS NULL
GROUP BY a.CODE
ORDER BY a.NAME ASC
本returns全部children无顶parent。
我现在尝试获取所有 Children 没有 children 的子选择,看起来像这样:
SELECT dac.CODE, dac.FULLPATH
FROM dir_asset_class as dac2
LEFT JOIN dir_asset_class as dac on locate(dac.CODE, dac2.FULLPATH) > 0
GROUP BY dac.CODE
HAVING (COUNT(dac.FULLPATH)-1) = 0
它工作了一半...它给了我一些 children 没有任何进一步的 children。但是很多都不见了。
有没有办法在没有程序的情况下解决这个问题(所以只有子选择?)
如果需要更多信息,请告诉我。
编辑:Link 到 SQLFiddle:http://sqlfiddle.com/#!9/cd8ff
试试这个 sqlfiddle
-- get all children that have no child, bottommost children
SELECT c1.*
FROM dir_asset_class as c1
LEFT JOIN dir_asset_class as c2
ON c1.code != c2.code
AND ( c2.FULLPATH like CONCAT(c1.code,'-%')
OR c2.FULLPATH like CONCAT('%-',c1.code,'-%')
OR c2.FULLPATH like CONCAT('%-',c1.code)
)
WHERE c2.code IS NULL
这里还有 sql 来计算根的所有子节点(父行为空的行)而无需 -1
-- get count of all children including grandchild of codes that have no parent
SELECT a.*,COUNT(c.CODE) as 'ChildCount'
FROM dir_asset_class as a
INNER JOIN dir_asset_class as c -- ON LOCATE(a.CODE, c.FULLPATH) > 0
ON c.FULLPATH like CONCAT(a.CODE,'-%')
WHERE a.PARENT IS NULL
AND a.code != c.code
GROUP BY a.CODE
ORDER BY a.NAME ASC;
更新:如果 FULLPATH 是唯一的并且 PARENT 引用它..我们可以使用 this sqlfiddle
SELECT c1.*
FROM dir_asset_class as c1
LEFT JOIN dir_asset_class as c2 ON c1.FULLPATH = c2.parent
WHERE c2.code IS NULL
and c1.parent IS NOT NULL
好的,这是我的看法:
SELECT * FROM `dir_asset_class` WHERE `CODE` NOT IN
(SELECT RIGHT(`PARENT`, LOCATE("-", RPAD(REVERSE(`PARENT`), 255, "-")) - 1)
FROM `dir_asset_class` WHERE PARENT IS NOT NULL ) ;
想法是获取所有未出现在 parent
值中的元素。为此,我们必须提取 parent
"tree" 的所有最后一项,这是通过子查询中的棘手事情完成的。我添加了一个 -
和 RPAD
以确保 parent
字符串中至少有一个 -
,否则它会导致树的顶部出现问题(s).
Returns :
+--------+-------------------------------+------------+------------------------+
| CODE | FULLPATH | NAME | PARENT |
+--------+-------------------------------+------------+------------------------+
| test3 | TEST-test2-test3 | 01. Test3 | TEST-test2 |
| test61 | TEST-test2-test4-test6-test61 | 01. Test61 | TEST-test2-test4-test6 |
| test62 | TEST-test2-test4-test6-test62 | 02. Test62 | TEST-test2-test4-test6 |
| test63 | TEST-test2-test4-test6-test63 | 03. Test63 | TEST-test2-test4-test6 |
| test5 | TEST-test5 | 02. Test5 | TEST |
| other | TEST-test7-other | 03. Other | TEST-test7 |
| test71 | TEST-test7-test71 | 01. Test71 | TEST-test7 |
| test72 | TEST-test7-test72 | 02. Test72 | TEST-test7 |
| other | Test10-other | 01. Other | Test10 |
| test9 | test8-test9 | 01. Test9 | test8 |
+--------+-------------------------------+------------+------------------------+
10 rows in set (0.00 sec)
这似乎是对的。