Я строю простую систему AGILE (что-то похожее на trello), где у меня есть несколько таблиц: пользователи, проекты, карты и некоторые другие, но здесь они не имеют значения.Вот структура таблиц:
Пользователи:
Проекты:
И карточки:
Мне нужно выбрать все проекты, где пользователи связаны с владельцем_id или проектом, чей идентификаторнаходится в таблице участников, в которой находится пользователь. Так что для простоты мне нужно найти все проекты, которыми владеет пользователь и где он является участником.
Я делаю это так:
SELECT * FROM app_site_agile_project AS project
LEFT JOIN (SELECT ID, display_name FROM app_site_users) users ON users.ID = '1'
LEFT JOIN (SELECT * FROM app_site_agile_project_participants) participants ON participants.participant_project_id = project.project_id
WHERE project.owner_id = '1' OR participants.participant_id = '1'
Это возвращает то, что я хочу.Но мне также нужно получить все карты для каждого проекта.Поэтому, если я добавлю еще одно объединение здесь:
SELECT * FROM app_site_agile_project AS project
LEFT JOIN (SELECT ID, display_name FROM app_site_users) users ON users.ID = '1'
LEFT JOIN (SELECT * FROM app_site_agile_project_participants) participants ON participants.participant_project_id = project.project_id
LEFT JOIN (SELECT * FROM app_site_agile_project_cards) cards ON cards.project_id = project.project_id
WHERE project.owner_id = '1' OR participants.participant_id = '1'
Возвращает карточки, но результат будет содержать столько строк, сколько карточек во всех проектах, и это не то, что я хочу.Однако я хочу иметь еще один столбец «карточка» для каждого результата проекта, который будет содержать все карточки в виде массива или массива json.Прямо сейчас я делаю второй запрос для каждого проекта, чтобы получить его.
ps Чтобы упростить вам воссоздание моей таблицы, я написал этот список запросов, просто запустите его в пустой базе данных, чтобы получитьточная копия моего
CREATE TABLE app_site_users
(
ID BIGINT(20) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
display_name VARCHAR(255) NOT NULL DEFAULT 'Incognito',
register_date DATETIME DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO `app_site_users` (`ID`, `display_name`, `register_date`) VALUES (NULL, 'User 1', current_timestamp());
INSERT INTO `app_site_users` (`ID`, `display_name`, `register_date`) VALUES (NULL, 'User 2', current_timestamp());
INSERT INTO `app_site_users` (`ID`, `display_name`, `register_date`) VALUES (NULL, 'User 3', current_timestamp());
INSERT INTO `app_site_users` (`ID`, `display_name`, `register_date`) VALUES (NULL, 'User 4', current_timestamp());
CREATE TABLE app_site_agile_project
(
project_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
owner_id BIGINT(20) UNSIGNED NOT NULL,
creation_time DATETIME DEFAULT CURRENT_TIMESTAMP,
project_name VARCHAR(255) NOT NULL,
last_update INT NOT NULL DEFAULT UNIX_TIMESTAMP()
COMMENT 'must also be updated on any dependent card changes',
FOREIGN KEY (owner_id) REFERENCES app_site_users (ID)
);
INSERT INTO `app_site_agile_project` (`project_id`, `owner_id`, `creation_time`, `project_name`) VALUES (NULL, '1', current_timestamp(), 'Some project 1');
INSERT INTO `app_site_agile_project` (`project_id`, `owner_id`, `creation_time`, `project_name`) VALUES (NULL, '1', current_timestamp(), 'Project 2');
INSERT INTO `app_site_agile_project` (`project_id`, `owner_id`, `creation_time`, `project_name`) VALUES (NULL, '2', current_timestamp(), 'Another project #3');
CREATE TABLE app_site_agile_project_participants
(
unique_participant_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
participant_project_id INT NOT NULL DEFAULT 0,
participant_id BIGINT(20) UNSIGNED NOT NULL,
participant_privilege INT NOT NULL DEFAULT 0,
FOREIGN KEY (participant_project_id) REFERENCES app_site_agile_project (project_id),
FOREIGN KEY (participant_id) REFERENCES app_site_users (ID)
);
INSERT INTO app_site_agile_project_participants (unique_participant_id, participant_project_id, participant_id, participant_privilege) VALUES (NULL, '1', '1', '0');
INSERT INTO app_site_agile_project_participants (unique_participant_id, participant_project_id, participant_id, participant_privilege) VALUES (NULL, '1', '3', '0');
CREATE TABLE app_site_agile_project_cards
(
card_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
project_id INT NOT NULL DEFAULT 0,
last_update INT NOT NULL DEFAULT UNIX_TIMESTAMP(),
creation_time DATETIME DEFAULT CURRENT_TIMESTAMP,
card_data JSON NOT NULL,
FOREIGN KEY (project_id) REFERENCES app_site_agile_project (project_id)
);
INSERT INTO app_site_agile_project_cards (card_id, card_data, creation_time, project_id, last_update) VALUES (NULL, '{"title": "Card 1"}', current_timestamp(), 1, UNIX_TIMESTAMP());
INSERT INTO app_site_agile_project_cards (card_id, card_data, creation_time, project_id, last_update) VALUES (NULL, '{"title": "Card 2"}', current_timestamp(), 1, UNIX_TIMESTAMP());
CREATE TABLE app_site_agile_project_specs
(
spec_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
last_update INT NOT NULL DEFAULT UNIX_TIMESTAMP(),
project_id INT COMMENT '',
spec_text TEXT NOT NULL,
FOREIGN KEY (project_id) REFERENCES app_site_agile_project (project_id)
);