Jochen,
...I want to display a tree like:
Software
Virenscanner
Linux
Debian Woody
Windows
Windowsd XP
Packprogramm
Sniffer
Hardware
Vermischtes
....
It looks more like a parts explosion than a tree (ie it seems to have
more than one root node). Perhaps you can hack this parts explosion
example into the shape you need ...
DROP TABLE IF EXISTS bom;
CREATE TABLE bom (
level SMALLINT,
nodeID SMALLINT,
parentID SMALLINT,
qty DECIMAL(10,2),
cost DECIMAL(10,2),
leftedge SMALLINT,
rightedge SMALLINT
);
DROP TABLE IF EXISTS edges;
CREATE TABLE edges LIKE tree;
DROP PROCEDURE IF EXISTS ShowComponents;
DELIMITER |
CREATE PROCEDURE ShowComponents( IN root INT )
BEGIN
DECLARE thischild, thisparent, rows, maxrightedge INT DEFAULT 0;
DECLARE thislevel, nextedgenum INT DEFAULT 1;
DECLARE thisqty, thiscost DECIMAL(10,2);
TRUNCATE edges;
TRUNCATE bom;
INSERT INTO edges
SELECT childID,parentID FROM assemblies WHERE assemblyRoot = root;
SET maxrightedge = 2 * (1 + (SELECT COUNT(*) FROM edges));
INSERT INTO bom
VALUES( thislevel, root, 0, 0, 0, nextedgenum, maxrightedge );
SET nextedgenum = nextedgenum + 1;
WHILE nextedgenum < maxrightedge DO
-- How many children of this node remain in the edges table?
SET rows = (
SELECT COUNT(*)
FROM bom AS s
INNER JOIN edges AS t ON s.nodeID=t.parentID AND s.level=thislevel
);
IF rows > 0 THEN
-- There is at least one child edge.
-- Compute qty and cost, insert into bom, delete from edges.
BEGIN
-- Alas MySQL nulls MIN(t.childid) when we combine the next two
queries
SET thischild = (
SELECT MIN(t.childID)
FROM bom AS s
INNER JOIN edges AS t ON s.nodeID=t.parentID AND s.level=thislevel
);
SET thisparent = (
SELECT DISTINCT t.parentID
FROM bom AS s
INNER JOIN edges AS t ON s.nodeID=t.parentID AND s.level=thislevel
);
SET thisqty = (
SELECT quantity FROM assemblies
WHERE assemblyroot = root
AND childID = thischild
AND parentID = thisparent
);
SET thiscost = (
SELECT a.assemblycost + (thisqty * (i.purchasecost +
i.assemblycost ))
FROM assemblies AS a
INNER JOIN items AS i ON a.childID = i.itemID
WHERE assemblyroot = root
AND a.parentID = thisparent
AND a.childID = thischild
);
INSERT INTO bom
VALUES(thislevel+1, thischild, thisparent, thisqty, thiscost,
nextedgenum, NULL);
DELETE FROM edges
WHERE childID = thischild AND parentID=thisparent;
SET thislevel = thislevel + 1;
SET nextedgenum = nextedgenum + 1;
END;
ELSE
BEGIN
-- Set rightedge, remove item from edges
UPDATE bom
SET rightedge=nextedgenum, level = -level
WHERE level = thislevel;
SET thislevel = thislevel - 1;
SET nextedgenum = nextedgenum + 1;
END;
END IF;
END WHILE;
SET rows := ( SELECT COUNT(*) FROM edges );
IF rows > 0 THEN
SELECT 'Orphaned rows remain';
ELSE
-- Percolate qty values up the graph
UPDATE bom AS c
INNER JOIN bom AS p
ON p.leftedge < c.leftedge
AND p.rightedge > c.rightedge
AND p.level = c.level + 1
AND p.qty <> 1
SET c.qty = c.qty * p.qty,
c.cost = c.cost * p.qty;
-- Total
SET thiscost = (SELECT SUM(qty) FROM bom);
UPDATE bom
SET qty = 1, cost = thiscost
WHERE nodeID = root;
-- Show the result
SELECT
CONCAT(Space(Abs(level)*2),ItemName(nodeid)) AS Item,
ROUND(qty,2) AS Qty,
ROUND(cost, 2) AS Cost
FROM bom
ORDER BY leftedge;
END IF;
END;
|
DELIMITER ;
PB
-----
Jochen Kaechelin wrote:
I have the following table:
mysql> select * from link_categories;
+----+-------+-------------+---------------+-----------+---------+
| id | level | category_id | category | parent_id | deleted |
+----+-------+-------------+---------------+-----------+---------+
| 1 | 1 | 1000 | Software | 0 | 0 |
| 2 | 1 | 2000 | Harware | 0 | 0 |
| 3 | 2 | 1001 | Virenscanner | 1000 | 0 |
| 4 | 2 | 1003 | Packprogramme | 1000 | 0 |
| 5 | 3 | 1004 | Linux | 1001 | 0 |
| 6 | 3 | 1005 | Windows | 1001 | 0 |
| 7 | 4 | 1006 | Windows XP | 1005 | 0 |
| 8 | 2 | 1007 | Sniffer | 1000 | 0 |
| 9 | 4 | 1008 | Debian Woody | 1004 | 0 |
| 10 | 1 | 100000 | Vermischtes | 0 | 0 |
+----+-------+-------------+---------------+-----------+---------+
10 rows in set (0.24 sec)
and I want to display a tree like:
Software
Virenscanner
Linux
Debian Woody
Windows
Windowsd XP
Packprogramm
Sniffer
Hardware
Vermischtes
....
Can someone give me hint how to build a query?
I run MySQL 4.1.x and 5.0.x and I use PHP.
Thanx.
--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.375 / Virus Database: 267.14.23/243 - Release Date: 1/27/2006
--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe: http://lists.mysql.com/[EMAIL PROTECTED]