Domanda

struttura della tabella

id    |    message    |    reply_id
1     |    help me!   |    0
434   |    love to    |    1
852   |    didn't work |    434
0110  |    try this   |    852
2200  |    this wont  |    0
5465  |    done. :)   |    0110

ho un ID "852" che si trova al centro del menu ad albero, ma voglio ottenere tutte le righe correlate precedenti e successive, quindi voglio ottenere i seguenti risultati come questo:

aiutami!> mi è piaciuto > non ha funzionato > provalo > fatto.:) (questo risultato viene visualizzato in questo modo dopo il ciclo php, ma inizia il ciclo dall'ID di avvio 1 con l'ID di risposta 0.

NOTA:L'ID 2200 non è stato visualizzato nel risultato perché non fa parte del gruppo.

È stato utile?

Soluzione

Ci sono diverse alternative per rendere le informazioni gerarchiche più facile lavorare con in SQL:

  • espressioni di tabella comuni (per lo standard SQL-2003) supportare query SQL ricorsive contro il tipo di genitore-id di dati che si sta utilizzando. Finora, MySql non supporta questa funzionalità. PostgreSQL 8.4, Microsoft SQL Server e IBM DB2 sono esempi di marche che supportano la sintassi RDBMS CTE. Oracle ha anche un'estensione di proprietà di sintassi SQL che supporta le query ricorsive.

  • Imposta nidificati (la soluzione a sinistra / destra che @phantombrain cita) è una soluzione dettagliato nel libro di Joe Celko "Alberi e gerarchie in SQL per Smarties" ed anche in numerosi articoli e blog messaggi su Internet.

  • Percorso Enumeration (aka materializzato Path) memorizza una stringa in ogni riga nella gerarchia per prendere nota del percorso degli antenati di quella riga. Combinate questo con le query LIKE per confrontare la stringa di percorso a percorsi e discendenti dei suoi antenati sentieri.

  • Chiusura tabella (aka transitivo Chiusura Relation) utilizza una seconda tabella per memorizzare tutti i rapporti antenato-discendente, non solo il padre immediato come nel progetto che si sta utilizzando. Molti tipi di query diventano più facili una volta che hai tutti i percorsi memorizzati.

  • soluzioni ibride anche esistere. Ad esempio, memorizzare l'id padre immediato, come si sta facendo, ma anche la radice dell'albero. Ora è possibile ottenere tutte le altre righe nella stessa gerarchia, li prendere in codice dell'applicazione, e risolvere l'albero con strutture di dati convenzionali.

Altri suggerimenti

presupponendo che siano voci di menu e non qualcosa di molto dinamico, come un forum, mi sento di raccomandare una modifica dello schema per aggiungere i valori di sinistra e destra per ogni elemento. Gli ID tra i valori a destra ea sinistra sono tutti i figli del nodo si sta interrogando. Così, è facile da fare una query per ottenere i valori di destra / sinistra, e una seconda query per ottenere gli elementi secondari.

http://www.sitepoint.com/print/hierarchical-data -database / per ulteriori informazioni

La ricorsione è il modo più elegante per farlo, ma non penso che mySql la supporti nelle funzioni personalizzate o nelle procedure memorizzate.Suggerirei un loop in una tabella temporanea o in una variabile di tabella per ottenere i tuoi ID, quindi unirti alla tabella ed eseguire una query sui risultati.Non conosco molto bene mySql, quindi non è stato testato, ma qualcosa in questo senso.

CREATE TEMPORARY TABLE tbl (myid int, ViewOrder int); 
Set @ifoundID=IdYourLookingFor;
Set @iStartID=@ifoundID;
Set @iOrder=0;
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);

BEGIN --get the ones going up
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=reply_id FROM YourTable WHERE id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder-1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

Set @ifoundID=@iStartID;
BEGIN --get the ones going down
 WHILE (@ifoundID Is Not Null) DO 
  SELECT @ifoundID=id FROM YourTable WHERE reply_id=@ifoundID; --find the next id
  SET @iOrder1=@iOrder+1; --increment the order
  INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
 END WHILE;
END

SELECT * FROM tbl INNER JOIN YourTable ON tbl.myid=YourTable.id ORDER BY ViewOrder

Spero possa aiutare

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top