在我的MySQL数据库中,我有一个名为units的表,其结构如下:
ID, Name, parentUnitID, UnitTypeID, ...
是否可以生成一个完整的单元链,其中包含一个查询和一个ID作为起点?只要给定ID有更多父级,就级联查询?在没有深度限制的情况下,我找不到生成此方法的方法。
给定的ID可能有一个父本身也有一个父母,也可能有一个,......等等。
编辑:
我期待的结果是这样的:
IDDepth1, IDDepth2, IDDepth3, ..., NameDepth1, NameDepth2, NameDepth3, ...
或者
UnitTypeID1, Name1,
UnitTypeID2, Name2,
UnitTypeID3, Name3,
...
获取给定ID的完整Unit-Chain并在PHP中解析它以构建级联数组。
EDIT2:
我试过这样的事情
SELECT ID, Name
FROM Units as u1
WHERE UnitTypeID = "4"
AND EXISTS (
SELECT ID, Name
FROM Units as u2
WHERE UnitTypeID = "5"
AND u2.ParentUnitID = u1.ID
AND EXISTS (
SELECT ID
FROM Units as u3
WHERE ID = "1692820"
AND u3.UnitTypeID = "6"
AND u3.ParentUnitID = u2.ID
)
);
但首先它是静态的,其次EXISTS的结果不是SELECT本身的一部分。
答案 0 :(得分:0)
你可以通过编写一个存储过程来实现这个目的,它会将父母ID插入临时表并循环访问父母等等。
我写了以下程序作为一个简单的例子;这当然不是完美的,但可以是一个开始
DELIMITER $$
drop procedure if exists get_unitschain$$
CREATE PROCEDURE get_unitschain (IN childUnitID INTEGER)
BEGIN
DROP TEMPORARY TABLE IF EXISTS tmp_chain; -- Will contain the parents ID's
DROP TEMPORARY TABLE IF EXISTS tmp_processed; -- Copy of tmp_chain
DROP TEMPORARY TABLE IF EXISTS tmp_parents; -- New parents identified by each WHILE loop
CREATE TEMPORARY TABLE tmp_chain (
ID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
UnitID INTEGER NOT NULL
);
CREATE TEMPORARY TABLE tmp_processed (
UnitID INTEGER NOT NULL
);
CREATE TEMPORARY TABLE tmp_parents (
UnitID INTEGER NOT NULL
);
INSERT INTO tmp_chain (UnitID) VALUES (childUnitId);
INSERT INTO tmp_parents (UnitID) VALUES (childUnitId); -- To start the WHILE loop
WHILE (SELECT COUNT(*) FROM tmp_parents) DO
DELETE FROM tmp_parents;
INSERT INTO tmp_parents (UnitID)
SELECT units.parentUnitID
FROM tmp_chain
INNER JOIN units ON units.ID = tmp_chain.UnitId
WHERE units.parentUnitID NOT IN (SELECT tmp_processed.UnitId FROM tmp_processed);
INSERT INTO tmp_chain (UnitID) SELECT tmp_parents.UnitID FROM tmp_parents;
INSERT INTO tmp_processed (UnitID) SELECT tmp_parents.UnitID FROM tmp_parents;
END WHILE;
SELECT units.UnitTypeID, units.Name FROM tmp_chain INNER JOIN units ON units.ID = tmp_chain.UnitID;
DROP TEMPORARY TABLE tmp_chain;
DROP TEMPORARY TABLE tmp_processed;
DROP TEMPORARY TABLE tmp_parents;
END$$
使用该程序:
CALL get_unitschain([child id]);