MySQL JOIN将来自一个表的结果作为JSON数组排成一行

时间:2019-06-16 10:06:13

标签: mysql left-join

我正在构建一个简单的AGILE系统(类似于trello),其中有多个表:用户,项目,卡片和其他一些表,但是在这里它们无关紧要。 这是表格的结构:

用户:

enter image description here

项目:

enter image description here

和卡片:

enter image description here

我需要选择用户与owner_id关联的所有项目,或者其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'

它返回卡片,但是结果将包含所有项目中与卡片一样多的行,这不是我想要的。我想要的是每个项目结果都有另一列“ card”,其中将所有卡片作为数组或json数组包含。 现在,我正在为每个项目进行第二次请求以获取它。

p.s。为了让您更轻松地重新创建表,我编写了此查询列表,只需在空数据库上运行它即可获得我的确切副本

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)
);

0 个答案:

没有答案