2016-03-02 9 views
7

Sto provando a scrivere una query sql su una tabella a soffietto.Query SQL per relazione genitori figli

╔════╦══════════╦═══════╗======╗======╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ 
╠════╬══════════╬═══════╣======║======║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 
║ 3 ║ LEO ║ YOGA ║  ║2  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 
║ 5 ║ STEFA ║ YOGA ║  ║3  ║ 
║ 6 ║ GLORIA ║ RUNN ║ 1 ║3  ║ 
╚════╩══════════╩═══════╝======╝======╝ 

E, in uscita per questa tabella dovrebbe essere come segue

╔════╦════════╦═══════╗======╗======╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ 
╠════╬════════╬═══════╣======║======║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 
║ 6 ║ GLORIA║ RUNN ║ 1 ║3  ║ 
║ 3 ║ LEO ║ YOGA ║  ║2  ║ 
║ 5 ║ STEFAN║ YOGA ║  ║3  ║ 
╚════╩════════╩═══════╝======╝======╝ 

So this is the explanation of the output 
First parent David as his DOB is 1, 
--David three childrens sorted based on DOB 
Then LEO as his DOB is 2 
-- Leo do not have children[if he did, would be here as sorted on DOB] 
Then Stefan as his DOB is 3 
-- Stefan do not have children [if he did, would be here as sorted on DOB] 

Così che cosa ho provato?

SELECT * FROM user group by ID, PARENT ; 

Sopra SQL, articoli di ritorno dichiarazione di gruppo dei bambini genitore, ma non non significa mantenere qualsiasi ordine, quando aggiungo ORDER BY, SQL non sembra come onorare GROUP BY più.

Poi ho provato a fare unire e finire con due tavoli diversi completi in cui uno contiene tutti i genitori e un altro contiene tutti i bambini. UNION ALL su quella query di due ha restituito il set di dati previsto ma non nell'ordine previsto.

Qualche idea?

UPDATE

Output should be 
Pick entry [based on min time ]. 
--use that id and find all of its children and placed them in sorted order 
repeat for every row in the table 

Nota:

--parents are sorted based on DOB 
--child's are also sorted based on DOB 
--DOB are valid timestamp 
--PARENT, ID field both are UUID and define as CHAR, PARENT reference to ID 

SQL Fiddle

Similar on SO

Update 1

Query nitrite

WITH RECURSIVE 
top AS (
    SELECT * FROM (SELECT * FROM user WHERE PARENT is null ORDER BY dob LIMIT 1) 
    UNION 
    SELECT user.NAME, user.PARENT, user.ID, user.CLASS, user.DOB FROM user, top WHERE user.PARENT=top.ID 
    ORDER BY user.dob 
) SELECT * FROM top; 

tornando seguente output:

╔════╦════════╦═══════╗======╗======╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ 
╠════╬════════╬═══════╣======║======║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 
║ 5 ║ GLORIA║ RUNN ║ 1 ║3  ║ 
╚════╩════════╩═══════╝======╝======╝ 

uscita è buono per primo genitore. Ma, ancora non riuscivo a capire, come posso scorrere il resto dei genitori e dei loro figli in ordine.

+0

L'output è lo stesso dell'input. Che cosa sta succedendo qui? –

+0

non appena ricontrollato, metto è diverso allora nel put. – minhaz

+0

L'unica differenza che vedo è l'ordinamento. Inoltre non mi fa impazzire l'uso di 'SELECT *' con un 'GROUP BY'. –

risposta

5

Query

SELECT u1.* 
FROM `user` u1 
LEFT JOIN `user` u2 
ON u1.PARENT = u2.ID 
ORDER BY CASE WHEN u1.PARENT IS NULL THEN u1.DOB ELSE u2.DOB END 
     || CASE WHEN u1.PARENT IS NULL THEN '' ELSE u1.DOB END; 

Spiegazione

  1. Alias ​​u1 ha tutti i dettagli di utente
  2. Alias ​​u2 ha dettagli della controllante se del caso. (A null viene utilizzato un null se l'utente u1 non ha un genitore.)
  3. Se l'utente non ha un genitore, utilizzare il proprio DOB ​​da solo per l'ordine.
  4. Se l'utente ha un genitore, prendere il DOB del genitore dell'utente e concatenare (aggiungere) il DOB dell'utente (figlio).

Risultati

I valori costruiti utilizzati per ORDER BY (che non sono effettivamente necessari nel SELECT) assomigliare la colonna più a destra qui:

╔════╦════════╦═══════╗======╗======╦════════╗ 
║ ID ║ NAME ║ CLASS ║PARENT║ DOB ║ORDER BY║ 
╠════╬════════╬═══════╣======║======╬════════║ 
║ 1 ║ DAVID ║ SPIN ║  ║1  ║ 1  ║ 
║ 2 ║ AROON ║ BIKE ║ 1 ║1  ║ 11  ║ 
║ 4 ║ LIN ║ CYC ║ 1 ║2  ║ 12  ║ 
║ 6 ║ GLORIA║ RUNN ║ 1 ║3  ║ 13  ║ 
║ 3 ║ LEO ║ YOGA ║  ║2  ║ 2  ║ 
║ 5 ║ STEFAN║ YOGA ║  ║3  ║ 3  ║ 
╚════╩════════╩═══════╝======╝======╩════════╝ 

Demo

Vedi SQL Fiddle Demo.

2

Ecco un ORDER BY che credo sia logicamente corretto:

ORDER BY COALESCE(PARENT, DOB) ASC, 
    CASE WHEN PARENT IS NULL THEN 0 ELSE DOB END 

Questa risposta presuppone, naturalmente, che si può effettivamente utilizzare le PARENT e DOB colonne nella query. Generalmente non si dovrebbero utilizzare le colonne SELECT che non sono né aggregate né specificate nella clausola GROUP BY.

Se PARENT e DOB essere definito come varchar allora si può provare gettandoli in un tipo numerico:

CAST(PARENT as integer) 

Si potrebbe desiderare di cambiare il disegno della tabella in modo che queste UUID sono di tipo numerico.

+0

Pensi che manterrà l'ordine rigoroso basato sul DOB? – minhaz

+0

Sì, credo che funzionerà. Per favore provalo e poi torna qui con quello che vedi. –

+0

sì, questo funziona perfettamente se 'genitore' e 'id' sono interi. ma, in questo caso, entrambi sono UUID e definiscono char. il campo dei prentri si riferisce fondamentalmente all'ID del genitore. Ho anche aggiunto il collegamento a SQL fiddle – minhaz

Problemi correlati