Mysql
 sql >> база данни >  >> RDS >> Mysql

Заявка за получаване на родителски записи с дъщерни записи, последвани от следващи записи родител-дете в mysql

Решението, което предлагам тук, използва концепцията за материализиран път. По-долу е даден пример за материализирани пътища, използващи вашите примерни данни. Надявам се, че ще ви помогне да разберете концепцията за материализиран път:

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

Всеки възел N има материализиран път, този път ви казва пътя да преминете от основния възел до възела N . Може да се изгради като конкатенира идентификаторите на възела. Например, за да достигнете до възел 5 започвайки от неговия основен възел, посещавате възел 1 , възел 3 и възел 5 , така че възел 5 материализираният път е 1.3.5

По съвпадение, поръчката, която търсите, може да бъде постигната чрез материализирания път.

В предишния пример материализираните пътища са изградени от конкатениращи низове, но аз предпочитам двоична конкатенация по редица причини.

За да изградите материализираните пътища, имате нужда от следния рекурсивен 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

Резултат:

+----+--------------------------+----------+----------------------------+
| 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 започва с основните възли. Изчисляването на материализирания път за основен възел е тривиално просто, това е идентификаторът на самия възел. На следващата итерация CTE свързва основните възли със своите дъщерни възли. Материализираният път за дъщерен възел CN е конкатенацията на материализирания път на неговия родителски възел PN и идентификатора на възел CN . Следващите итерации напредват с едно ниво надолу в дървото, докато се достигнат листните възли.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL MAX_JOIN_SIZE грешки

  2. Mysql Max с групиране по заявка

  3. Преобразуване на дата в MySQL от полето низ

  4. Най-добрият начин за улавяне на грешка ЗАРЕЖДАНЕ НА ДАННИ LOCAL INFILE?

  5. sunspot solr недефиниран тип поле