MySQL - 使用物化路径方法列出 parents children
MySQL - Listing a parents children using the Materialised Path approach
正如您将从下面的示例中看到的,我有一个 user
table,其中有两个重要的列:
ManagerUserId
- 该特定用户的管理员。
Lineage
- 此专栏来自 Materialised Path 方法,如果对在 MySQL 中存储分层数据的另一种方式感兴趣,请阅读。存储从当前用户到最顶层管理员的路径。
我想做的是:输入某人的姓名和return他们所有的直接下属(children).
我们通过查看 Lineage
列并执行 LIKE
计算出某人的直接下属,例如:
WHERE Lineage LIKE ('1.2%')
这将 return 其 Lineage
值以 1.2
开头的所有元素。
我一直在摆弄它,并在下面提供了我的尝试,我希望这能阐明我的目标。
在MySQL-8.0:
select version();
| version() |
| :-------- |
| 8.0.13 |
CREATE TABLE user (
`Id` INT primary key,
`Name` VARCHAR(55),
`ManagerUserID` INTEGER,
`Depth` INTEGER,
`Lineage` VARCHAR(255)
);
✓
INSERT INTO user (
`Id`, `Name`, `ManagerUserID`, `Depth`,
`Lineage`
)
VALUES
('1', 'User 1', NULL, 0, '1.'),
('2', 'User 2', '1', 1, '1.2.'),
('3', 'User 3', '4', 3, '1.2.4.3.'),
('4', 'User 4', '2', 2, '1.2.4.'),
('5', 'User 5', '2', 2, '1.2.5.');
✓
SELECT * from user;
Id | Name | ManagerUserID | Depth | Lineage
-: | :----- | ------------: | ----: | :-------
1 | User 1 | null | 0 | 1.
2 | User 2 | 1 | 1 | 1.2.
3 | User 3 | 4 | 3 | 1.2.4.3.
4 | User 4 | 2 | 2 | 1.2.4.
5 | User 5 | 2 | 2 | 1.2.5.
SELECT u.Id, u.Name, u.ManagerUserId, u.Depth, u.Lineage
FROM user u
LEFT JOIN user m ON m.Id = u.ManagerUserId
WHERE u.Lineage LIKE (m.Lineage + '%') AND m.Name = 'User 2'
ORDER BY u.Lineage + u.Depth
Id | Name | ManagerUserId | Depth | Lineage
-: | :--- | ------------: | ----: | :------
db<>fiddle here
这为 'User 2'
下的儿童产生了结果
SELECT u.Id, u.Name, u.ManagerUserId, u.Depth, u.Lineage
FROM user u
LEFT JOIN user m ON m.Id = u.ManagerUserId
WHERE m.Name = 'User 2'
ORDER BY u.Lineage + u.Depth
更新答案:
SELECT u.Id, u.Name, u.ManagerUserId, u.Depth, u.Lineage,m.id, m.Lineage
FROM user u, user m
WHERE m.Id = u.ManagerUserId
and u.Lineage like concat((select Lineage from user where name='User 2'),"%")
and u.Lineage!= (select Lineage from user where name='User 2')
ORDER BY concat(u.Lineage , u.Depth)
正如您将从下面的示例中看到的,我有一个 user
table,其中有两个重要的列:
ManagerUserId
- 该特定用户的管理员。Lineage
- 此专栏来自 Materialised Path 方法,如果对在 MySQL 中存储分层数据的另一种方式感兴趣,请阅读。存储从当前用户到最顶层管理员的路径。
我想做的是:输入某人的姓名和return他们所有的直接下属(children).
我们通过查看 Lineage
列并执行 LIKE
计算出某人的直接下属,例如:
WHERE Lineage LIKE ('1.2%')
这将 return 其 Lineage
值以 1.2
开头的所有元素。
我一直在摆弄它,并在下面提供了我的尝试,我希望这能阐明我的目标。
在MySQL-8.0:
select version();
| version() | | :-------- | | 8.0.13 |
CREATE TABLE user ( `Id` INT primary key, `Name` VARCHAR(55), `ManagerUserID` INTEGER, `Depth` INTEGER, `Lineage` VARCHAR(255) );
✓
INSERT INTO user ( `Id`, `Name`, `ManagerUserID`, `Depth`, `Lineage` ) VALUES ('1', 'User 1', NULL, 0, '1.'), ('2', 'User 2', '1', 1, '1.2.'), ('3', 'User 3', '4', 3, '1.2.4.3.'), ('4', 'User 4', '2', 2, '1.2.4.'), ('5', 'User 5', '2', 2, '1.2.5.');
✓
SELECT * from user;
Id | Name | ManagerUserID | Depth | Lineage -: | :----- | ------------: | ----: | :------- 1 | User 1 | null | 0 | 1. 2 | User 2 | 1 | 1 | 1.2. 3 | User 3 | 4 | 3 | 1.2.4.3. 4 | User 4 | 2 | 2 | 1.2.4. 5 | User 5 | 2 | 2 | 1.2.5.
SELECT u.Id, u.Name, u.ManagerUserId, u.Depth, u.Lineage FROM user u LEFT JOIN user m ON m.Id = u.ManagerUserId WHERE u.Lineage LIKE (m.Lineage + '%') AND m.Name = 'User 2' ORDER BY u.Lineage + u.Depth
Id | Name | ManagerUserId | Depth | Lineage -: | :--- | ------------: | ----: | :------
db<>fiddle here
这为 'User 2'
下的儿童产生了结果SELECT u.Id, u.Name, u.ManagerUserId, u.Depth, u.Lineage
FROM user u
LEFT JOIN user m ON m.Id = u.ManagerUserId
WHERE m.Name = 'User 2'
ORDER BY u.Lineage + u.Depth
更新答案:
SELECT u.Id, u.Name, u.ManagerUserId, u.Depth, u.Lineage,m.id, m.Lineage
FROM user u, user m
WHERE m.Id = u.ManagerUserId
and u.Lineage like concat((select Lineage from user where name='User 2'),"%")
and u.Lineage!= (select Lineage from user where name='User 2')
ORDER BY concat(u.Lineage , u.Depth)