Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapytanie, aby uzyskać rekordy rodzica z rekordem dziecka, a następnie następne rekordy rodzic-dziecko w mysql

Proponowane przeze mnie rozwiązanie wykorzystuje koncepcję zmaterializowanej ścieżki. Poniżej znajduje się przykład zmaterializowanych ścieżek wykorzystujących przykładowe dane. Mam nadzieję, że pomoże ci to zrozumieć koncepcję zmaterializowanej ścieżki:

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

Każdy węzeł N ma zmaterializowaną ścieżkę, ta ścieżka wskazuje drogę od węzła głównego do węzła N . Można go zbudować łącząc identyfikatory węzła. Na przykład, aby dotrzeć do węzła 5 zaczynając od węzła głównego, odwiedzasz węzeł 1 , węzeł 3 i węzeł 5 , więc węzeł 5 zmaterializowana ścieżka to 1.3.5

Przypadkowo, kolejność, której szukasz, można uzyskać poprzez zmaterializowaną ścieżkę.

W poprzednim przykładzie zmaterializowane ścieżki są jedynie konkatenacją ciągów, ale wolę konkatenację binarną z wielu powodów.

Aby zbudować zmaterializowane ścieżki, potrzebujesz następującego rekurencyjnego CTE:

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

Wynik:

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

Powyższe rekurencyjne CTE zaczyna się od węzłów głównych. Obliczenie zmaterializowanej ścieżki dla węzła głównego jest banalnie proste, jest to identyfikator samego węzła. W następnej iteracji CTE łączy węzły główne z węzłami podrzędnymi. Zmaterializowana ścieżka węzła podrzędnego CN jest konkatenacją zmaterializowanej ścieżki jego węzła nadrzędnego PN i identyfikator węzła CN . Kolejne iteracje przesuwają się o jeden poziom w dół na drzewie, aż do osiągnięcia węzłów liści.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy timestampdiff() w MySQL jest odpowiednikiem datediff() w SQL Server?

  2. Konwertuj BufferedInputStream na obraz

  3. Konwertuj wynik sql na listę python

  4. Jak przekonwertować te dziwne postacie? (Ă«, Ă, ì, Ă¹, Ă)

  5. Używanie grupowania według na dwóch polach i liczenia w SQL