Il DBMS con cui sto lavorando è MySQL, l'ambiente di programmazione è Delphi 7 (che non è molto importante per questo esempio).SQL e Delphi: meccanismo ricorsivo per la creazione di un albero da una tabella
Ho una tabella denominata "oggetto" in cui memorizzo tutti gli oggetti del libro nel sistema. I soggetti possono avere una relazione genitore-figlio, come la scienza può essere divisa, diciamo, in matematica e fisica, mentre la matematica può essere suddivisa in calcolo, algebra, geometria e via.
Quello che mi piacerebbe è creare un albero popolato con la data da quella tabella. Per favore, aiutami a farlo. Non importa nemmeno quale linguaggio usi a scopo illustrativo, può semplicemente essere pseudocodice.
Il diagramma di database per la tabella soggetto guarda in questo modo:
La definizione Soggetto tavolo:
DROP TABLE IF EXISTS subject;
CREATE TABLE IF NOT EXISTS subject ( # Comment
subject_id INT UNSIGNED NOT NULL AUTO_INCREMENT, # Subject ID
subject VARCHAR(25) NOT NULL, # Subject name
parent_id INT UNSIGNED NULL DEFAULT NULL, # Parent ID as seen from
PRIMARY KEY (subject_id), # the diagram refers to
UNIQUE (subject), # the subject_id field
INDEX (parent_id),
CONSTRAINT fk_subject_parent
FOREIGN KEY (parent_id)
REFERENCES subject (subject_id)
ON DELETE RESTRICT
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
popolamento tavolo Soggetto con alcuni dati dummy:
INSERT INTO subject (subject, parent_id) VALUES
('Science', NULL),
('Mathematics', 1),
('Calculus', 2),
('Algebra', 2),
('Geometry', 2),
('Languages', NULL),
('English', 6),
('Latin', 6);
L'istruzione SELECT restituisce questo:
SELECT * FROM subject;
╔════════════╦═════════════╦═══════════╗
║ subject_id ║ subject ║ parent_id ║
╠════════════╬═════════════╬═══════════╣
║ 1 ║ Science ║ NULL ║
║ 2 ║ Mathematics ║ 1 ║
║ 3 ║ Calculus ║ 2 ║
║ 4 ║ Algebra ║ 2 ║
║ 5 ║ Geometry ║ 2 ║
║ 6 ║ Languages ║ NULL ║
║ 7 ║ English ║ 6 ║
║ 8 ║ Latin ║ 6 ║
╚════════════╩═════════════╩═══════════╝
Le stored procedure:
DELIMITER$$
DROP PROCEDURE IF EXISTS get_parent_subject_list;
CREATE PROCEDURE get_parent_subject_list()
BEGIN
SELECT subject_id, subject
FROM subject
WHERE parent_id IS NULL
ORDER BY subject ASC;
END$$
DROP PROCEDURE IF EXISTS get_child_subject_list;
CREATE PROCEDURE get_child_subject_list (IN parentID INT)
BEGIN
SELECT subject_id, subject
FROM subject
WHERE parent_id = parentID
ORDER BY subject ASC;
END$$
DELIMITER ;
successivo è la mia procedura di Delphi che tenta di popolare una vista ad albero con i dati, ma come si può vedere ulteriormente, non si può ottenere qualsiasi più profondo del secondo livello :
procedure TForm1.CreateSubjectTreeView(Sender: TObject);
var
i : integer;
begin
i := 0;
q1.SQL.Clear;
q1.SQL.Add('CALL get_parent_subject_list()');
q1.Open;
q1.First;
while not q1.EOF do
begin
TreeView.Items.Add(nil, q1.Fields[1].Value);
q2.SQL.Clear;
q2.SQL.Add('CALL get_child_subject_list(' +
VarToStr(q1.Fields[0].Value) + ')');
q2.Open;
q2.First;
while not q2.EOF do
begin
TreeView.Items.AddChild(TreeView.Items.Item[i], q2.Fields[1].Value);
q2.Next;
end;
i := TreeView.Items.Count;
q1.Next;
end;
end;
questo è ciò che questo frammento di codice fa:
+- Science
| |
| +- Mathematics
|
+- Languages
|
+- English
+- Latin
Ma vorrei farlo sembrare come questo:
+- Science
| |
| +- Mathematics
| |
| +- Calculus
| +- Algebra
| +- Geometry
|
+- Languages
|
+- English
+- Latin
+1 per la domanda ben formato –
io non posso aiutarti con la soluzione di mysql, ma quello che stai cercando è una query gerarchica, e un esempio può essere trovato qui: http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/ mysql non ha una clausola connect, quindi dovresti farlo manualmente. –