@tukreb

Заполнять таблицу пустышками или имитировать в виртуальной таблице?

Допустим есть таблицы
container:
id | name          | capacity
++++++++++++++++++++++
1  | Container 1   |  30

container_blocks:
id_container | id_block | position_of_block 
++++++++++++++++++++++
1           |  1        |  2
1           |  2        |  6

block:
id | name     | block_size
++++++++++++++++++++++
1  | block1   |  3
2  | block2   |  5


Условие, вывести список свободных позиций, исключив те, что заняты блоками.
То есть начальный список:
1,2,3,4,5,6,7,8,9,10,11,12 ... 30


С занимаемые блоками должен быть:
1,5,11,12 ... 30


То есть не показывать позиции, которые заняли блоки (блоки больше 1 размера могут занимать несколько позиций).

Как такое лучше решить?
1. Заполнять таблицу container_blocks: пустышками при создание нового контайнера?
container_blocks:
id_container | id_block | position_of_block 
++++++++++++++++++++++
1           |  NULL      |  1
1           |  NULL      |  2
1           |  NULL      |  3
1           |  NULL      |  4
1           |  NULL      |  5
...
1           |  NULL      |  30

И заполнять NULL блоком те позиции, которые он займёт, например блок с id 1 с размером 3:
id_container | id_block | position_of_block 
++++++++++++++++++++++
1           |  NULL      |  1
1           |  1         |  2
1           |  1         |  3
1           |  1         |  4
1           |  NULL      |  5
...
1           |  NULL      |  30


И потом относительно простым запросом выбрать свободные строки со значениями NULL и сформировать нужный список со свободными позициями.

2. Строить SQL запросами виртуальные таблицы, и оттуда выбирать готовый список.

Например, как-то так дублируем записи блоков, которые занимают больше 1 позиции за раз, при этом может быть много join.
with recursive multiple(i, id_block, position, some_important_field) as (
    select 1, id_block, position, z.some_important_field
    from container_blocks
        left join a
        left join b
        ...
        left join z --добираемся до какой то информации
    UNION ALL
    select m.i + 1, c.id_block, c.position, z2.some_important_field
    from multiple AS m, container_blocks AS c
        left join a2
        left join b2
        ...
        left join z2--добираемся до какой то информации
    where m.id_block = c.id_block and m.i < c.position and z2.some_important_field = some_value)
select id_block, position, some_important_field from multiple;

и потом ещё одним запросом формируем окончательный список
1,5,11,12 ... 30

где исключены позиции занятые 2 блоками.

Так вот, что будет лучше и правильней?
  • Вопрос задан
  • 63 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы