2016-03-02 13 views
7

Próbuję napisać zapytanie sql na tabeli poniżej.Zapytanie SQL dla relacji z rodzicami dzieci

╔════╦══════════╦═══════╗======╗======╗ 
║ 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  ║ 
╚════╩══════════╩═══════╝======╝======╝ 

A, wyjście dla tej tabeli powinno być następujące

╔════╦════════╦═══════╗======╗======╗ 
║ 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] 

Więc co próbowałem?

SELECT * FROM user group by ID, PARENT ; 

Przede SQL, powrotne rzeczy oświadczenie w macierzystej grupy dzieci, ale nie nie utrzymuje dowolnej kolejności, kiedy dodać ORDER BY, SQL nie wydaje się już uhonorowanie GROUP BY.

Potem próbowałem połączyć i zakończyć z dwoma kompletnymi tabelami, w których jeden zawiera wszystkich rodziców, a drugi zawiera wszystkie dzieci. UNION ALL w tej dwóch kwerendach zwrócił oczekiwany zestaw danych, ale nie w oczekiwanej kolejności.

Jakieś myśli?

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 

Uwaga:

--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

Zapytanie ryczeć

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; 

powrocie następujące wyjścia:

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

Wyjście jest dobre dla pierwszego rodzica. Ale wciąż nie mogłem zrozumieć, jak mogę powtarzać przez resztę rodziców i ich dzieci w uporządkowanej kolejności.

+0

Wyjście wygląda tak samo jak wejście. Co tu się dzieje? –

+0

Po prostu ponownie sprawdzone put jest inny niż w put. – minhaz

+0

Jedyna różnica jaką widzę, to kolejność. Nie szaleję też za używaniem 'SELECT *' z 'GROUP BY'. –

Odpowiedz

5

Zapytanie

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; 

Wyjaśnienie

  1. Alias ​​u1 posiada wszystkie dane użytkownika
  2. Alias ​​u2 zawiera dane jednostki dominującej gdzie stosowne. (Jest używany kod A LEFT JOIN, więc wszystkie te szczegóły będą dostępne pod warunkiem, że użytkownik nie ma rodzica.)
  3. Jeśli użytkownik nie ma rodzica, użyj DOB do samodzielnego zamówienia.
  4. Jeśli użytkownik ma rodzica, weź DOB rodzica użytkownika i dołącz (dołącz) DOB użytkownika (dziecka).

Wyniki

konstruowanej wartości używane do ORDER BY (które w rzeczywistości nie są potrzebne w SELECT) wyglądają jak skrajnej prawej kolumnie tutaj:

╔════╦════════╦═══════╗======╗======╦════════╗ 
║ 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

Zobacz SQL Fiddle Demo.

2

Oto ORDER BY który moim zdaniem jest logicznie poprawne:

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

Ta odpowiedź zakłada oczywiście, że rzeczywiście można korzystać z PARENT i DOB kolumn w zapytaniu. Generalnie nie należy kolumn SELECT, które nie są agregatami lub określone w klauzuli GROUP BY.

Jeśli PARENT i DOB być zdefiniowana jako varchar to można spróbować rzucając je do typu numerycznego:

CAST(PARENT as integer) 

Możesz chcieć zmienić swój projekt stołu tak, że te UUID są typu numerycznego.

+0

Czy myślisz, że zachowa ścisłą kolejność na podstawie DOB? – minhaz

+0

Tak, wierzę, że to zadziała. Spróbuj go, a następnie wróć tutaj z tym, co widzisz. –

+0

tak działa to doskonale, jeśli "parent" i "id" są liczbami całkowitymi. ale w tym przypadku oba są UUID i zdefiniowane jako char. pole prent w zasadzie odnosi się do identyfikatora rodzica. Dodałem także link do skrzypiec SQL – minhaz