Qual è il modo più semplice per get tutti i genitori di un record usando il model id / parent_id in mysql / php?

Sto cercando il modo più semplice per get ricorsivamente tutti gli elementi genitore da un database utilizzando l'elenco di adiacenza / model di ereditarietà di tabelle singole ( id, parent_id ).

La mia selezione al momento è simile a questa:

 $sql = "SELECT e.id, TIME_FORMAT(e.start_time, '%H:%i') AS start_time, $title AS title, $description AS description, $type AS type, $place_name AS place_name, p.parent_id AS place_parent_id, p.city AS place_city, p.country AS place_country FROM event AS e LEFT JOIN place AS p ON p.id = e.place_id LEFT JOIN event_type AS et ON et.id = e.event_type_id WHERE e.day_id = '$day_id' AND e.private_flag = 0 ORDER BY start_time"; 

Ogni event è collegato a un place e each place può essere figlio di un altro place (fino a circa 5 livelli di profondità)

È ansible in una singola selezione con mysql?

Al momento sto pensando che potrebbe essere una function separata che scorre attraverso l'arrays $events restituito, aggiungendo place_parent_X elementi place_parent_X come va, ma non sono sicuro di come implementarlo.

È ansible farlo in MySQL , ma dovrai creare una function e utilizzarla in una query.

Vedi questa voce nel mio blog per le spiegazioni dettagliate:

  • Query gerarchiche in MySQL

Ecco la function e la query:

 CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT NOT DETERMINISTIC READS SQL DATA BEGIN DECLARE _id INT; DECLARE _parent INT; DECLARE _next INT; DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL; SET _parent = @id; SET _id = -1; IF @id IS NULL THEN RETURN NULL; END IF; LOOP SELECT MIN(id) INTO @id FROM place WHERE parent = _parent AND id > _id; IF @id IS NOT NULL OR _parent = @start_with THEN SET @level = @level + 1; RETURN @id; END IF; SET @level := @level - 1; SELECT id, parent INTO _id, _parent FROM place WHERE id = _parent; END LOOP; END SELECT id, parent FROM ( SELECT hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level FROM ( SELECT @start_with := 0, @id := @start_with, @level := 0 ) vars, t_hierarchy WHERE @id IS NOT NULL ) ho JOIN place hi ON hi.id = ho.id 

Quest'ultima query selezionerà tutti i discendenti di un dato nodo (che dovresti impostare nella variabile @start_with )

Per trovare tutti gli antenati di un determinato nodo è ansible utilizzare una query semplice senza funzioni:

 SELECT @r AS _id, @r := ( SELECT parent FROM place WHERE id = _id ) AS parent FROM ( SELECT @r := @node_id ) vars, place 

Questo articolo nel mio blog ha descritto questa domanda in modo più dettagliato:

  • Liste di sorting

Affinché entrambe queste soluzioni funzionino in tempi ragionevoli, è necessario disporre degli indici sia id sia sul parent .

Assicurati che il tuo id sia definito come PRIMARY KEY e hai un secondo indice su parent .

Non è ansible con il progetto DB standard padre-figlio.

Tuttavia, è ansible utilizzare un approccio di set nidificato e farlo in una query, anche se ci vorrà un bel po 'di lavoro per arrivare a quel punto.

Sembra che il più semplice sia il set annidato .