2016-03-02 17 views
7

Tôi đang cố gắng viết một truy vấn sql trên bảng dưới đây.Truy vấn SQL cho mối quan hệ cha mẹ con

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

Và, đầu ra cho bảng này nên được như sau

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

Vì vậy, những gì tôi đã cố gắng?

SELECT * FROM user group by ID, PARENT ; 

Trên SQL, các mục tuyên bố trở lại trong cha mẹ trẻ nhóm nhưng không phải không duy trì bất kỳ thứ tự, khi tôi thêm ORDER BY, SQL không có vẻ như tôn vinh GROUP BY nữa.

Sau đó, tôi đã cố gắng để tham gia và kết thúc với hai bảng hoàn chỉnh khác nhau, nơi một chứa tất cả các bậc cha mẹ và một số khác có chứa tất cả trẻ em. UNION ALL trên hai truy vấn đó đã trả về bộ dữ liệu dự kiến ​​nhưng không phải theo thứ tự mong muốn.

Mọi suy nghĩ?

CẬP NHẬT

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 

Lưu ý:

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

Cập nhật 1

Query rống lên

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; 

trở về sau đầu ra:

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

Output là tốt cho cha mẹ đầu tiên. Nhưng, vẫn không thể tìm ra, làm thế nào tôi có thể lặp lại thông qua phần còn lại của cha mẹ và con cái của họ theo thứ tự sắp xếp.

+0

Đầu ra trông giống như đầu vào. Chuyện gì đang xảy ra ở đây? –

+0

không chỉ rechecked ra đặt là khác nhau sau đó trong đặt. – minhaz

+0

Sự khác biệt duy nhất tôi thấy là thứ tự. Tôi cũng không điên về việc sử dụng 'SELECT *' với một 'GROUP BY'. –

Trả lời

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; 

Giải thích

  1. Bí danh u1 có tất cả chi tiết người dùng
  2. Bí danh u2 có chi tiết của phụ huynh khi áp dụng. (A LEFT JOIN được sử dụng để các chi tiết này sẽ là null nếu người dùng u1 không có cha/mẹ.)
  3. Nếu người dùng không có cha mẹ, hãy sử dụng DOB của riêng mình để đặt hàng.
  4. Nếu người dùng có cha/mẹ, hãy lấy DOB của cha mẹ của người dùng và nối (thêm) DOB của người dùng (con).

Kết quả

Các giá trị xây dựng sử dụng để ORDER BY (mà không thực sự cần thiết trong SELECT) trông giống như cột ngoài cùng bên phải ở đây:

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

Xem SQL Fiddle Demo.

2

Dưới đây là một ORDER BY mà tôi tin là logic đúng:

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

câu trả lời này giả định tất nhiên rằng bạn thực sự có thể sử dụng các cột PARENTDOB trong truy vấn của bạn. Thông thường, bạn không được SELECT cột không phải là tổng hợp hoặc được chỉ định trong mệnh đề GROUP BY.

Nếu PARENTDOB được định nghĩa là varchar sau đó bạn có thể thử đúc chúng vào một loại số:

CAST(PARENT as integer) 

Bạn có thể muốn thay đổi thiết kế bảng của bạn để các UUIDs là loại số.

+0

Bạn có nghĩ rằng, nó sẽ giữ trật tự nghiêm ngặt dựa trên DOB? – minhaz

+0

Vâng, tôi tin điều này sẽ hiệu quả. Hãy thử nó và sau đó quay trở lại đây với những gì bạn nhìn thấy. –

+0

có điều này hoạt động hoàn hảo nếu 'cha mẹ' và 'id' là số nguyên. nhưng, trong trường hợp này cả hai đều là UUID và xác định là char. trường prent về cơ bản chỉ đến id của cha mẹ. tôi cũng đã thêm liên kết vào SQL fiddle – minhaz

Các vấn đề liên quan