3

私は2つのテーブルを持っています

:車に関する階層データが含まれています

+-----+-------------+-----------+
| 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を持つ)が1つの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 |
+--------+----------+--------+

ここで、 carscar_mappingに基づいて3番目のテーブルcars_newを作成します。これにより、重複を削除し、 car_mappingテーブルのフィールドに基づいてcarsテーブルの階層を再入力します。結果のcars_newは次のとおりです。map_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フィドルです。この階層を再入力する方法はありますか?

4

3 に答える 3

1

階層はありません。階層を作成しない方がよいでしょう。"cars" テーブルに車が記述されていないことに注意してください。数値に文字列を割り当てるだけです (およびその数値に別の数値を割り当てます)。最初から「すべての車」は車ではなく、「トヨタ」は車ではなく自動車メーカーです。

一意性の問題を解決し、クエリを簡素化する解決策は、個別のものごとに 1 つのテーブルを使用することです。

  • メーカー { mfg_id, name } -- GM、フォードなど
  • make { make_id, name, mfg_id } -- シボレー、リンカーンなど。メーカーへのリンク
  • models { name, make_id } -- 例: Yaris など。メーカーへのリンク。

偽の ID が作成されるのを防ぐために、各テーブルで「名前」を必ず一意にしてください。

これにより、製造年、販売数、各モデルのドア数など、これらの物が発生したときに新しい属性を割り当てることができます。また、フォードと GM の「関係」を防ぐこともできます。 、たとえば、ヤリスを「すべての車」の親にします。

(ところで、テーブル名に「マップ」または「マッピング」を使用しないことをお勧めします。これは、何も言わないためです。すべてのテーブルは、行内の要素を相互に関連付けます。すべてのテーブルは、キーをその値にマップします。良いニュースは、car_mapping テーブルが新しいデザインで消えることです。)

既存のcarsテーブルをどう変換するかというと、面倒くさい。 cars_mapping が正しいと仮定すると、各テーブルに挿入して結合し、名前でグループ化しながら min(id) を取得できます。このようなクエリが 3 つ必要です。その後、不整合をチェックするための注意深い観察が続きます。

于 2013-01-16T05:32:46.680 に答える
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テーブルでは、あなたが望む結果を正確に得るために1行(下の最初の行)が必要です:

+--------+----------+--------+
| 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 に答える