Стандартный способ SQL сделать это с 2 таблицами
create table routine (
id serial primary key,
name text
);
create table exercises (
routine_id integer references routine(id) on delete cascade /*optional*/,
exercise text
);
Postgres дает хороший синтаксис (хотя и не на 100% стандартном) для создания подпрограмм с упражнениями за 1 раз:
with new_routine_id as (
insert into routine(name)
values ('Chest')
returning id
)
insert into exercises
select id, unnest(array['Bench Press', 'Skull Crusher', 'Incline Bench Press'])
from new_routine_id
Выбор такой же, как и следовало ожидать:
select id, name, array_agg(exercise order by exercise /*it could be ordered using an additional field*/) as exercises
from routine
join exercises on id = routine_id
group by id, name
редактирует
@klin опубликовал альтернативное решение с 1 таблицей, содержащей массив для упражнений напрямую. Решение совершенно корректно и, в некотором смысле, проще моего (я все-таки упомянул это решение в своем первом комментарии).
ИМХО, есть 1 причина, по которой решение будет "лучше", чем другое. Вы работаете в команде, где все знают, как обращаться с массивами?
- ДА: выберите решение @ klin
- НЕТ: выберите мое решение выше. Вы можете делать все, что вам нужно, только с обычными
JOIN
, без массивов.