Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Permintaan untuk mendapatkan catatan induk dengan catatan anak, diikuti oleh catatan induk-anak berikutnya di mysql

Solusi yang saya usulkan di sini menggunakan konsep materialized path. Berikut ini adalah contoh jalur terwujud menggunakan data sampel Anda. Saya harap ini membantu Anda untuk memahami konsep jalur terwujud:

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

Setiap simpul N memiliki jalur yang terwujud, jalur ini memberi tahu Anda cara untuk pergi dari simpul akar ke simpul N . Itu dapat dibangun dengan menggabungkan id simpul. Misalnya, untuk mencapai simpul 5 mulai dari simpul akarnya, Anda mengunjungi simpul 1 , simpul 3 , dan simpul 5 , jadi simpul 5 jalur terwujud adalah 1.3.5

Secara kebetulan, pesanan yang Anda cari dapat dicapai dengan memesan melalui jalur yang terwujud.

Pada contoh sebelumnya, jalur yang dimaterialisasikan adalah string gabungan yang dibangun, tetapi saya lebih suka penggabungan biner karena beberapa alasan.

Untuk membangun jalur yang terwujud, Anda memerlukan CTE rekursif berikut:

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

Hasil:

+----+--------------------------+----------+----------------------------+
| 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 rekursif di atas dimulai dengan node root. Menghitung jalur yang terwujud untuk simpul akar sangat mudah, ini adalah ID dari simpul itu sendiri. Pada iterasi berikutnya CTE menggabungkan node root dengan node anaknya. Jalur terwujud untuk simpul anak CN adalah rangkaian dari jalur yang terwujud dari simpul induknya PN dan id dari simpul CN . Iterasi berikutnya naik satu tingkat ke bawah pada pohon sampai simpul daun tercapai.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kueri dari dua tabel dalam laporan

  2. Bagaimana cara MEMESAN DENGAN SUM () di MySQL?

  3. Bagaimana cara memasukkan beberapa nilai kotak centang ke dalam tabel?

  4. Bagaimana cara mendapatkan semua posting dengan semua kategori di wordpress melalui mysql?

  5. Mengapa beberapa jenis kueri yang disiapkan menggunakan PDO di PHP dengan MySQL lambat?