Polega na tym że w TREE znajduje się mapa zagnieżdzenia (id rodzielone kropką).
Dodatkowo stosuje dopełnianie zerami, w celu utrzymania kolejności zagnieżdzenia (prawidłowe sortowanie liczb, które są łańcuchem znaków a nie typem INT). 10 cyfrowa liczba ponieważ ID (INTEGER) może mieć największą wartość równą 4 294 967 295.
Przy polu tree o długości 255 znaków możliwe jest utworzenie 23 poziomów.
Jeśli pole będzie typu TEXT będzie napewno o wiele więcej.
Tabela:
Kod
+-----------+-------------------+------+-----+------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------------+------+-----+------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| parent_id | int(10) | NO | | 0 | |
| tree | varchar(255) | NO | | 0000000000 | |
| depth | int(100) unsigned | NO | | 0 | |
| name | varchar(255) | NO | | NULL | |
| position | int(10) unsigned | NO | | 0 | |
+-----------+-------------------+------+-----+------------+----------------+
6 rows in set (0,00 sec)
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------------+------+-----+------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| parent_id | int(10) | NO | | 0 | |
| tree | varchar(255) | NO | | 0000000000 | |
| depth | int(100) unsigned | NO | | 0 | |
| name | varchar(255) | NO | | NULL | |
| position | int(10) unsigned | NO | | 0 | |
+-----------+-------------------+------+-----+------------+----------------+
6 rows in set (0,00 sec)
Tworzymy tabelę
CREATE TABLE `drzewko` ( `id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , `parent_id` INT( 10 ) NOT NULL DEFAULT '0', `tree` VARCHAR( 255 ) NOT NULL DEFAULT '0000000000', `depth` INT( 100 ) UNSIGNED NOT NULL DEFAULT '0', `name` VARCHAR( 255 ) NOT NULL , `position` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0' ) ENGINE = MYISAM;
Dodajemy dane
INSERT INTO `drzewko` (`id`, `parent_id`, `tree`, `depth`, `name`, `position`) VALUES (1, 0, '0000000000', 0, 'Tomek', 2), (2, 0, '0000000000', 0, 'Jacek', 1), (3, 2, '0000000000.0000000002', 1, 'Placek', 2), (4, 2, '0000000000.0000000002', 1, 'Gacek', 3), (5, 2, '0000000000.0000000002', 1, 'Kowalski', 1), (6, 5, '0000000000.0000000002.0000000005', 2, 'Nowak', 1), (7, 1, '0000000000.0000000001', 1, 'Pod kategoria', 0);
Wyświetlenie drzewka:
SELECT * FROM `drzewko` ORDER BY CONCAT(tree,'.', LPAD(id,10,0))
Wynik:
Kod
+----+-----------+----------------------------------+-------+---------------+----------+
| id | parent_id | tree | depth | name | position |
+----+-----------+----------------------------------+-------+---------------+----------+
| 1 | 0 | 0000000000 | 0 | Tomek | 2 |
| 7 | 1 | 0000000000.0000000001 | 1 | Pod kategoria | 0 |
| 2 | 0 | 0000000000 | 0 | Jacek | 1 |
| 3 | 2 | 0000000000.0000000002 | 1 | Placek | 2 |
| 4 | 2 | 0000000000.0000000002 | 1 | Gacek | 3 |
| 5 | 2 | 0000000000.0000000002 | 1 | Kowalski | 1 |
| 6 | 5 | 0000000000.0000000002.0000000005 | 2 | Nowak | 1 |
+----+-----------+----------------------------------+-------+---------------+----------+
| id | parent_id | tree | depth | name | position |
+----+-----------+----------------------------------+-------+---------------+----------+
| 1 | 0 | 0000000000 | 0 | Tomek | 2 |
| 7 | 1 | 0000000000.0000000001 | 1 | Pod kategoria | 0 |
| 2 | 0 | 0000000000 | 0 | Jacek | 1 |
| 3 | 2 | 0000000000.0000000002 | 1 | Placek | 2 |
| 4 | 2 | 0000000000.0000000002 | 1 | Gacek | 3 |
| 5 | 2 | 0000000000.0000000002 | 1 | Kowalski | 1 |
| 6 | 5 | 0000000000.0000000002.0000000005 | 2 | Nowak | 1 |
+----+-----------+----------------------------------+-------+---------------+----------+
Wszystko ładnie się wyświetla w odpowiednim porządku, ponieważ stosuje dopełnianie z lewej strony zerami.
Ale to czego potrzebuje to posortować te wyniki dodatkowo według pozycji (position).
Na tym etapie trzeba wprowadzić warunek: sortowane mają być wiersze według pola position które mają taki sam parent_id.
Czyli najpierw sortowane są względem struktury drzewiastej a teraz tam gdzie parent_id jest wspólny chce dodatkowo posortować według pola position.
Napewno trzeb będzie zrobić SELECTA z SELECTA, ale nie wiem jak do tego postawić warunek że mają się sortować według pola position tylko te pola które mają ten sam parent_id.
SELECT * FROM (SELECT * FROM `drzewko` ORDER BY CONCAT(tree,'.', LPAD(id,10,0))) ORDER BY position ...?