Domanda

Ho il tuo run of the mill nidificato impostare la gerarchia del set di impostazioni con le seguenti colonne:

nome tabella:

myset

colonne:

id, name, lft, rgt

Qualcuno conosce una query per determinare il genitore di un nodo?

Ho letto un paio di posti che è utile avere anche una colonna parent_id nella tua tabella per tenerne traccia, ma sembra ridondante e sembra che potrebbe non essere sincronizzato con il nidificato impostato se una query è stata eseguita in modo errato durante l'aggiunta / rimozione / spostamento di qualcosa all'interno del set.

È stato utile?

Soluzione

Guarda questa domanda . È simile al tuo. Ho pubblicato lì una domanda di cui potresti aver bisogno.

SELECT title, (SELECT TOP 1 title 
           FROM tree t2 
           WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt    
           ORDER BY t2.rgt-t1.rgt ASC) AS parent
FROM tree t1
ORDER BY rgt-lft DESC

Spero che ci sia quello di cui hai bisogno.

Per la seguente tabella:

+-------------+----------------------+-----+-----+
| category_id | name                 | lft | rgt |
+-------------+----------------------+-----+-----+
|           1 | ELECTRONICS          |   1 |  20 |
|           2 | TELEVISIONS          |   2 |   9 |
|           3 | TUBE                 |   3 |   4 |
|           4 | LCD                  |   5 |   6 |
|           5 | PLASMA               |   7 |   8 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |
|           7 | MP3 PLAYERS          |  11 |  14 |
|           8 | FLASH                |  12 |  13 |
|           9 | CD PLAYERS           |  15 |  16 |
|          10 | 2 WAY RADIOS         |  17 |  18 |

produce l'output:

title                | parent
----------------------------------------------
ELECTRONICS          | NULL
PORTABLE ELECTRONICS | ELECTRONICS
TELEVISIONS          | ELECTRONICS
MP3 PLAYERS          | PORTABLE ELECTRONICS
FLASH                | MP3 PLAYERS
CD PLAYERS           | PORTABLE ELECTRONICS
2 WAY RADIOS         | PORTABLE ELECTRONICS
TUBE                 | TELEVISIONS
LCD                  | TELEVISIONS
PLASMA               | TELEVISIONS

Altri suggerimenti

TOP è un comando MSSQL, utilizza LIMIT per MySQL:

SELECT title, (SELECT title 
       FROM tree t2 
       WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt    
       ORDER BY t2.rgt-t1.rgt ASC
       LIMIT 1) 
AS parent FROM tree t1 
ORDER BY (rgt-lft) DESC

Dovrebbe fare il trucco ..

solo per aggiungere a queste risposte che mi hanno aiutato molto,

in alcuni casi avevo bisogno di trovare il genitore immediato di un nodo, nonché il genitore di livello superiore di una catena di nodi,

Ho usato quanto segue come base per ottenere gli articoli in ordine da figlio a genitore

SELECT parent.*  FROM
        nested_set node,
        nested_set parent
        WHERE (
            node.set_left BETWEEN parent.set_left AND parent.set_right          
        )
        AND node.set_id={CHILD_NODE_ID_HERE}
        ORDER BY parent.set_right - parent.set_left
        #LIMIT 1,1

si tratta quindi di aggiungere LIMIT 1,1 per acquisire solo la seconda riga che sarebbe il genitore immediato

si dovrebbe anche notare che con la query sopra se il nodo stesso è il genitore di livello superiore, allora NON avrebbe un genitore immediato , quindi con il >= <= dovrebbe restituire un set di risultati vuoto

per ottenere il genitore di livello superiore ho invertito la clausola order by, incluso un controllo se il nodo stesso è il genitore top e limitato il risultato alla prima riga

SELECT parent.* AS top_level_right FROM
        nested_set node,
        nested_set parent
        WHERE (
            node.set_left >= parent.set_left 
            AND node.set_left <= parent.set_right
        )
        AND node.set_id={CHILD_NODE_ID_HERE}
        ORDER BY parent.set_left - parent.set_right
        LIMIT 1

nell'ultima query ho usato <=> operatori in modo che l'intervallo selezionato comprenda il nodo figlio se si tratta anche del genitore di livello superiore

Ho avuto un problema con la domanda di Lucasz. La mia versione di mysql non capiva il comando TOP. Ho dovuto usare LIMIT. Ecco il codice rivisto.

SELECT 
   `id`, 
   (SELECT 
      `id`
    FROM 
       `[*** YOUR TABLE ***]` AS `t2` 
    WHERE 
       `t2`.`left_id`  < `t1`.`left_id`AND 
       `t2`.`right_id` > `t1`.`right_id`
    ORDER BY 
       `t2`.`right_id`-`t1`.`right_id`ASC 
    LIMIT 
       1) AS `parent`
FROM 
    `[*** YOUR TABLE ***]` AS `t1`
WHERE 
    `t1`.`id` = [*** ID OF THE NODE WHOS PARENT YOU WISH TO LOOKUP ***]
ORDER BY 
    `right_id`-`left_id` DESC

Ovviamente, cambia le cose in [] per adattarle alle tue esigenze. Rimuovi anche []. Questa query restituisce solo UNA riga. In questo modo ...

id  parent
7   3
select * from myset
  where lft < :lftOfCurrent and rgt > :lftOfCurrent
  order lft desc
  limit 1

È possibile utilizzare un numero massimo anziché ordine / limite e potrebbe essere necessaria un'altra parola chiave per limitare i risultati a una riga a seconda del database. Tra piuttosto che & Lt; e > funzionerebbe se il tuo database restituisse il set esclusivo, cosa che MySQL no.

SELECT parent.name 
FROM myset AS node, myset AS parent 
WHERE parent.lft < node.lft 
AND parent.rgt > node.rgt 
AND node.id = {YOUR CATEGORY ID} 
ORDER BY ( parent.rgt - parent.lft ) ASC LIMIT 1;

Tutti gli antenati vengono restituiti da

SELECT id FROM thetable
WHERE x BETWEEN lft and rgt;

Quindi, il genitore diretto è l'antenato con la più piccola differenza tra lft e rgt.

SELECT id FROM thetable
WHERE x BETWEEN lft and rgt
ORDER BY (rgt-lft)
LIMIT 1

Il codice di spankmaster79 non era completamente sbagliato. Ho modificato il suo codice e ha funzionato.

SELECT parent . * FROM Nested_Category AS node, Nested_Category AS parent 
enter code hereWHERE node.leftSide
BETWEEN parent.leftSide
AND parent.rightSide
AND node.id ='Enter the Node ID'
ORDER BY (
parent.rightSide - parent.leftSide
)
LIMIT 1 , 1
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top