Как переписать иерархию в таблице?

У меня есть две таблицы

cars : содержит данные иерархии о машинах

+-----+-------------+-----------+ | 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 : содержит данные отображения, в которых дубликаты автомобилей (с разными идентификаторами) сопоставляются с одним идентификатором.

 +--------+----------+--------+ | 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 на основе автомобилей и car_mapping, которая удаляет дубликаты и переустанавливает иерархию в таблице автомобилей на map_id поля map_id в таблице car_mapping . Вот результирующие cars_new :

 +--------+----------+---------------+ | 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 для этого вопроса. Любые идеи о том, как заново закрепить эту инициативу?

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

Основываясь на принятом ответе @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; 

У вас нет иерархии, и вам лучше не создавать ее. Обратите внимание, что ваш стол «автомобили» не описывает автомобили; он просто присваивает строку числу (и другому номеру для этого числа). С самого начала «все автомобили» – это не автомобиль, а «Тойота» – производитель автомобилей, а не автомобиль.

Решение, которое поможет вам решить проблему уникальности и упростит ваши запросы, – это использовать одну таблицу для каждой отдельной вещи:

  • производит {mfg_id, name} – например, GM, Ford
  • делает {make_id, name, mfg_id} – например, Chevrolet, Lincoln; ссылки на производство
  • модели {name, make_id} – например, Yaris и т. д .; ссылки на make.

Не забудьте сделать «имя» уникальным в каждой из таблиц, чтобы предотвратить создание ложных идентификаторов.

Это позволит вам назначать новые атрибуты этим вещам по мере их возникновения, такие как годы, когда они были сделаны или сколько было продано, или количество дверей каждой модели. Это также позволит вам предотвратить «отношения» Ford с GM или , скажем, заставляя Яриса родителем «всех автомобилей».

(Кстати, я предлагаю вам отказаться от «карты» или «сопоставления» в имени таблицы, потому что она ничего не говорит. Каждая таблица связывает элементы в строке друг с другом. Каждая таблица сопоставляет ключ с его значениями. что ваш стол car_mapping исчезает в новом дизайне.)

Что касается того, как преобразовать существующую таблицу автомобилей, это будет неприятно. Предполагая, что cars_mapping прав, вы сможете вставлять их в каждую таблицу, присоединяться к ней и принимать min (id) при группировке по имени. Вам понадобятся три таких запроса, за которыми следует тщательное наблюдение, чтобы проверить, er, несоосность.

  • Изменение кода JDBC с SQL Server на Oracle
  • Как объединить вставки данных из курсора ref во временную таблицу в PL / SQL
  • SQL: Возможно ли использовать поля SUM () типа INTERVAL?
  • Oracle коррелирует UPDATE
  • Можно ли вычислить сумму каждой группы в таблице без использования группового предложения
  • Oracle DB: вернуть второй запрос, если первый запрос пуст
  • T-SQL эквивалент оператора Oracle TYPE?
  • Запрос SQL для поля имени без алфавита
  • Преобразование PL / sql в T-SQL
  • Как получить первые n записей по каждой категории
  • В чем разница между PL / SQL и T-SQL?
  • Interesting Posts

    Объедините две таблицы, в которых различное количество строк на SQL-сервере

    Группа T-SQL по задаче

    Разбор / Разрушение Огромный комплекс XML-базы данных SQL Server 2008 (более 30 таблиц)

    Создание SQL-скриптов для SQL Server с использованием студии управления SQL

    Добавить Конкретный день, год, месяц, неделю в конкретную дату с использованием сервера sql

    Быстрая вставка из C # CLR

    Выберите дату + 3 дня, не включая выходные и праздничные дни

    SQL Sever Pivot Многие столбцы

    Проверьте, существует ли разница между двумя строками

    Force DateTime с базой данных Entity Framework First

    SQL Query Count – объединение двух таблиц и получение счета, даже если оно равно 0

    Ошибка «System.Guid», потому что материализованное значение равно null. Либо общий параметр типа результата, либо запрос должны использовать тип с нулевым значением

    Order BY не поддерживается в sql-сервере

    Использует ли MS SQL Server «между» границы диапазона?

    Не удалось загрузить файл или сборку в c #

    Давайте будем гением компьютера.