Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Truy vấn để lấy các bản ghi cha với bản ghi con, theo sau là các bản ghi cha-con tiếp theo trong mysql

Giải pháp tôi đề xuất ở đây sử dụng khái niệm con đường vật chất hóa. Sau đây là một ví dụ về các đường dẫn cụ thể hóa bằng cách sử dụng dữ liệu mẫu của bạn. Tôi hy vọng nó sẽ giúp bạn hiểu khái niệm đường dẫn cụ thể hóa:

+----+--------------------------+----------+------------------+
| ID |           Name           | ParentID | MaterializedPath |
+----+--------------------------+----------+------------------+
|  1 | Parent 1                 |        0 | 1                |
|  2 | Parent 2                 |        0 | 2                |
|  4 | Parent 2 Child 1         |        2 | 2.4              |
|  6 | Parent 2 Child 1 Child 1 |        4 | 2.4.6            |
|  7 | Parent 2 Child 1 Child 2 |        4 | 2.4.7            |
|  3 | Parent 1 Child 1         |        1 | 1.3              |
|  5 | Parent 1 Child 1 Child   |        3 | 1.3.5            |
+----+--------------------------+----------+------------------+

Mỗi nút N có một đường dẫn cụ thể hóa, đường dẫn này cho bạn biết cách đi từ nút gốc đến nút N . Nó có thể được xây dựng nối các id của nút. Ví dụ:để đến nút 5 bắt đầu từ nút gốc của nó, bạn truy cập vào nút 1 , nút 3 và nút 5 , vì vậy nút 5 đường dẫn cụ thể hóa là 1.3.5

Thật trùng hợp, thứ tự bạn đang tìm kiếm có thể đạt được thứ tự bằng con đường cụ thể hóa.

Trong ví dụ trước, các đường dẫn cụ thể hóa là các chuỗi nối liền nhau, nhưng tôi thích nối nhị phân hơn vì một số lý do.

Để xây dựng các đường dẫn cụ thể hóa, bạn cần CTE đệ quy sau:

CREATE TABLE Tree
(
    ID int NOT NULL CONSTRAINT PK_Tree PRIMARY KEY, 
    Name nvarchar(250) NOT NULL,
    ParentID int NOT NULL,
)

INSERT INTO Tree(ID, Name, ParentID) VALUES
(1, 'Parent 1', 0),
(2, 'Parent 2', 0),
(3, 'Parent 1 Child 1', 1),
(4, 'Parent 2 Child 1', 2),
(5, 'Parent 1 Child 1 Child', 3),
(6, 'Parent 2 Child 1 Child 1', 4),
(7, 'Parent 2 Child 1 Child 2', 4)

GO
WITH T AS
(
    SELECT
        N.ID, N.Name, N.ParentID, CAST(N.ID AS varbinary(512)) AS MaterializedPath
    FROM
        Tree N
    WHERE
        N.ParentID = 0

    UNION ALL

    SELECT
        N.ID, N.Name, N.ParentID, CAST( T.MaterializedPath + CAST(N.ID AS binary(4)) AS varbinary(512) ) AS MaterializedPath
    FROM
        Tree N INNER JOIN T
            ON N.ParentID = T.ID

)
SELECT *
FROM T
ORDER BY T.MaterializedPath

Kết quả:

+----+--------------------------+----------+----------------------------+
| ID |           Name           | ParentID |      MaterializedPath      |
+----+--------------------------+----------+----------------------------+
|  1 | Parent 1                 |        0 | 0x00000001                 |
|  3 | Parent 1 Child 1         |        1 | 0x0000000100000003         |
|  5 | Parent 1 Child 1 Child   |        3 | 0x000000010000000300000005 |
|  2 | Parent 2                 |        0 | 0x00000002                 |
|  4 | Parent 2 Child 1         |        2 | 0x0000000200000004         |
|  6 | Parent 2 Child 1 Child 1 |        4 | 0x000000020000000400000006 |
|  7 | Parent 2 Child 1 Child 2 |        4 | 0x000000020000000400000007 |
+----+--------------------------+----------+----------------------------+

CTE đệ quy ở trên bắt đầu với các nút gốc. Việc tính toán đường dẫn cụ thể hóa cho một nút gốc rất đơn giản, đó là ID của chính nút đó. Trong lần lặp tiếp theo, CTE kết hợp các nút gốc với các nút con của nó. Đường dẫn cụ thể hóa cho nút con CN là sự kết hợp của đường dẫn cụ thể hóa của nút cha của nó PN và id của nút CN . Các lần lặp tiếp theo tiến xuống một cấp trên cây cho đến khi đạt đến các nút lá.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. làm thế nào để nhận được một báo cáo lỗi chi tiết khi một tập lệnh php-mysql không thành công?

  2. Có FIND_IN_SET theo chỉ mục trong MySQL không?

  3. Sử dụng UUID làm khóa chính với Laravel 5

  4. 'False' có thể khớp với một số chuỗi trong mysql không?

  5. Làm thế nào để có được một thứ hạng hàng?