Как объединить таблицу polymorphi c с ее дочерними таблицами? - PullRequest
0 голосов
/ 24 февраля 2020

Я сожалею о том, что не могу лучше сформулировать название вопроса или описание этого вопроса. Тем не менее, я приведу схему, пример данных и ожидаемый результат. Пожалуйста, помогите мне написать запрос для такого варианта использования.

Схема ресторанов

id
name
item_type
item_id

Схема продуктов

id 
name

Схема food_items

id 
name
food_id

Пример данных в ресторанах

|---------------------|------------------|---------------------|------------------|
|      id             |     name         |      item_type      |     item_id      |
|---------------------|------------------|---------------------|------------------|
|       1             | Apple Crushers   |      food_items     |         1        |
|---------------------|------------------|---------------------|------------------|
|       2             |     Retro Cafe   |      foods          |         2        |
|---------------------|------------------|---------------------|------------------|
|       3             | Fruit Mania      |      foods          |         1        |
|---------------------|------------------|---------------------|------------------|
|       4             | Meat and Eat     |      NULL           |        NULL      |
|---------------------|------------------|---------------------|------------------|

Пример данных в продуктах питания:

|---------------------|------------------|
|      id             |     Name         |  
|---------------------|------------------|
|       1             |     Fruits       |     
|---------------------|------------------|
|       2             |     Chocolates   | 
|---------------------|------------------|

Пример данных в food_items

|---------------------|------------------|---------------------|
|      id             |     Name         |      food_id        | 
|---------------------|------------------|---------------------|
|       1             |     Apple        |        1            | 
|---------------------|------------------|---------------------|
|       2             |     Mango        |        1            | 
|---------------------|------------------|---------------------|

Мне нужно написать запрос так, чтобы я получил его в качестве результата.

|---------------------|------------------|---------------------|------------------|---------------------|------------------|
|      r_id           |     r_name       |      food_id        |     food_name    |    food_item_id     | food_item_name   |
|---------------------|------------------|---------------------|------------------|---------------------|------------------|
|       1             | Apple Crushers   |      1              |         Fruit    |        1            |  Apple           |
|---------------------|------------------|---------------------|------------------|---------------------|------------------|
|       2             |     Retro Cafe   |      2              |      Chocolates  |        NULL         |     NULL         |
|---------------------|------------------|---------------------|------------------|---------------------|------------------|
|       3             | Fruit Mania      |      1              |       Fruit      |      NULL           |    NULL          |
|---------------------|------------------|---------------------|------------------|---------------------|------------------|
|       4             | Meat and Eat     |      NULL           |        NULL      |         NULL        |       NULL       |
|---------------------|------------------|---------------------|------------------|---------------------|------------------|

ps: Было бы очень полезно, если бы кто-то смог придумать подходящий заголовок и описание для этой проблемы. Я потерян для слов, чтобы описать это.

Ответы [ 3 ]

1 голос
/ 24 февраля 2020

Вы должны дважды присоединиться к столу и использовать COALESCE:

select
  r.id,
  r.name,
  coalesce(f.id, fif.id) as food_id,
  coalesce(f.name, fif.name) as food_name,
  fi.id as food_item_id,
  fi.name as food_item_name
from restaurants r
left join foods f on f.id = r.item_id and r.item_type = 'foods'
left join food_items fi on fi.id = r.item_id and r.item_type = 'food_items'
left join foods fif on fif.id = fi.food_id
order by r.id;
0 голосов
/ 24 февраля 2020

Для вашей базы данных я бы предложил другую модель данных на основе составных ключей. Это гарантирует согласованность данных и делает запросы немного проще:

food_group
(
  food_group_no  integer       not null,
  name           varchar(100)  not null,
  primary key (food_group_no)
);

food
(
  food_group_no  integer       not null,
  food_no        integer       not null,
  name           varchar(100)  not null,
  primary key (food_group_no, food_no)
);

restaurant
(
  restaurant_no  integer       not null,
  name           varchar(100)  not null,
  food_group_no  integer       not null,
  food_no        integer       null,
  primary key (restaurant_id),
  foreign key (food_group_no) references food_group(food_group_no),
  foreign key (food_group_no, food_no) references food(food_group_no, food_no)
);

Запрос:

select
  r.restaurant_no,
  r.name as restaurant_name,
  fg.food_group_no,
  fg.name as food_group_name,
  f.food_id,
  f.name as food_name
from restaurants r
join food_group fg on fg.id = r.food_group_no
left join food f on f.food_group_no = r.food_group_no and f.food_no = r.food_no
order by r.id;
0 голосов
/ 24 февраля 2020
select r.id, r.name, foods.id, foods.name, food_items.id, food_items.name from restaurents as r 
left join food_items on r.item_type = 'food_items' and r.item_id = food_items.id
left join foods on (r.item_type = 'foods' and r.item_id = foods.id) or (r.item_type = 'foods' and r.item_id = food_items.food_id) 

У этого могут быть некоторые синтаксические проблемы, связанные с именами таблиц, но это должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...