3

我有两张桌子

汽车:包含有关汽车的层次结构数据

+-----+-------------+-----------+
| id  | description | parent_id |
+-----+-------------+-----------+
|   1 | All cars    |         1 |
|  30 | Toyota      |         1 |
|  34 | Yaris       |        30 |
|  65 | Yaris       |        30 |
|  87 | Avensis     |        30 |
|  45 | Avensis     |        30 |
| 143 | Skoda       |         1 |
| 199 | Octavia     |       143 |
|  12 | Yeti        |       143 |
+-----+-------------+-----------+

car_mapping:包含映射数据,其中重复的汽车(具有不同的 id)被映射到一个 id。

+--------+----------+--------+
| car_id | car_name | map_id |
+--------+----------+--------+
|     34 | Yaris    |      1 |
|     65 | Yaris    |      1 |
|     87 | Avensis  |      2 |
|     45 | Avensis  |      2 |
|    199 | Octavia  |      3 |
|     12 | Yeti     |      4 |
|     30 | Toyota   |      5 |
|    143 | Skoda    |      6 |
|      1 | All cars |      0 |
+--------+----------+--------+

现在,我们的想法是创建第三个表cars_new,它基于carscar_mapping删除重复项并根据car_mapping表中的字段重新键入cars表中的层次结构。这是生成的cars_newmap_id

+--------+----------+---------------+
| map_id | car_name | parent_map_id |
+--------+----------+---------------+
|      0 | All      |             0 |
|      1 | Yaris    |             5 |
|      2 | Avensis  |             5 |
|      3 | Octavia  |             6 |
|      4 | Yeti     |             6 |
|      5 | Toyota   |             0 |
|      6 | Skoda    |             0 |
+--------+----------+---------------+

这是这个问题的SQL Fiddle。任何想法如何重新设置这个层次结构?

4

3 回答 3

1
select distinct cm.map_id, cm.car_name, cm2.map_id parent_map_id
from cars c, car_mapping cm, car_mapping cm2
where c.id = cm.car_id
and c.parent_id = cm2.car_id(+)
order by cm.map_id;

PS:在您的car_mapping表格中,您需要额外的一行(下面的第一行)才能获得您想要的结果:

+--------+----------+--------+
| car_id | car_name | map_id |
+--------+----------+--------+
|     1  | All      |      0 |
|     34 | Yaris    |      1 |
|     65 | Yaris    |      1 |
Etc..
于 2013-01-15T19:02:44.273 回答
1

根据@Majid LAISSI 接受的答案,这似乎适用于 Oracle 和 SQL Server:

select distinct cm.map_id, cm.car_name, cm2.map_id as parent_map_id
from cars c
left outer join car_mapping cm on c.id = cm.car_id
left outer join car_mapping cm2 on c.parent_id = cm2.car_id
order by cm.map_id;
于 2013-01-15T19:47:46.193 回答
1

您没有层次结构,最好不要创建层次结构。注意你的“汽车”表没有描述汽车;它只是将一个字符串分配给一个数字(并将另一个数字分配给该数字)。从一开始,“所有汽车”就不是汽车,“丰田”是汽车制造商,而不是汽车。

解决方案 - 有助于解决您的唯一性问题并简化您的查询 - 是为每个不同的事物使用一个表:

  • 制造商 { mfg_id, name } -- 例如 GM、Ford
  • 制造 { make_id, name, mfg_id } -- 例如雪佛兰、林肯;制造商链接
  • models { name, make_id } -- 例如 Yaris 等;链接到制造。

确保在每个表中使“名称”唯一,以防止创建虚假 ID。

这将让您在这些东西出现时为其分配新属性,例如它们的制造年限或售出数量,或每种型号的门数。它还可以让您防止福特与通用汽车或通用汽车的“关系”比如说,让 Yaris 成为“所有汽车”的父级。

(顺便说一句,我建议您避免在表名中使用“映射”或“映射”,因为它没有说明任何内容。每个表都将行中的元素相互关联。每个表都将键映射到其值。好的新闻是您的 car_mapping 表在新设计中消失了。)

至于如何转换现有的汽车表,那就麻烦了。 假设cars_mapping 是正确的,您将能够插入每个表,加入它并在按名称分组时获取 min(id)。您将需要三个这样的查询,然后仔细观察以检查,呃,错位。

于 2013-01-16T05:32:46.680 回答