从树父获取信息作为列

Get information from tree parent as column

我有地理位置数据。这可能是城市、省、州、国家、大陆或任何类型的位置。一个位置可以是另一个位置的一部分,就像一个州是一个国家的一部分(如美国),但荷兰有省份。城市可以在一个省内,但不一定是一个省的一部分。部分原因是有些城市是城邦(类似)(即卢森堡),但在我的情况下,如果我的位置列表中只有一个国家的城市,那么它甚至与城市所在的省份无关。

这个非常简单的例子:

| types     |
|-----------|
| Continent |
| Country   |
| Province  |
| City      |


Locations

| id | name          | type      | parent |
|----|---------------|-----------|--------|
| 1  | Europe        | Continent | NULL   |
| 2  | Netherlands   | Country   | 1      |
| 3  | Noord-Holland | Province  | 2      |
| 4  | Amsterdam     | City      | 3      |
| 5  | Haarlem       | City      | 3      |
| 6  | Luxembourg    | City      | 1      |

我想知道每个地点的 'geographical parent'(如果存在)。所以预期的结果是这样的:

| id | name          | type      | Continent | Country     | Province      |
|----|---------------|-----------|-----------|-------------|---------------|
| 1  | Europe        | Continent |           |             |               |
| 2  | Netherlands   | Country   | Europe    |             |               |
| 3  | Noord-Holland | Province  | Europe    | Netherlands |               |
| 4  | Amsterdam     | City      | Europe    | Netherlands | Noord-Holland |
| 5  | Haarlem       | City      | Europe    | Netherlands | Noord-Holland |
| 6  | Luxembourg    | City      | Europe    |             |               |

如何将所有 types 作为我的位置 table 的列?我试过使用子查询,但由于递归性,我完全被卡住了:阿姆斯特丹不是一个国家的一部分(但它是省),而卢森堡是一个国家的一部分(没有省)。

如何获得预期的输出?

当然有更好的解决方案,但目前我写了这个:

SELECT Locations.id,
       Locations.name,
       Locations.type,
       IF(l3.name IS NULL, IF(l2.name IS NULL, IFNULL(l1.name, ''), l2.name), l3.name) as Continent,
       IF(l3.name IS NULL, IF(l2.name IS NULL, '', l1.name), l2.name)                  as Country,
       IF(l3.name IS NULL, '', l1.name)                                                as Province
FROM Locations
         LEFT join Locations l1 on Locations.parent = l1.id
         LEFT join Locations l2 on l1.parent = l2.id
         LEFT join Locations l3 on l2.parent = l3.id
ORDER BY Locations.id

DEMO