0

所以这里是问题:

我有一个“成员”表,其中包含成员及其属性(姓名、生日、邮件等)。这些成员可能属于组(假设有 3 个组),从无到全部。这些组在表(“组”)中引用,因此我可以根据需要添加/删除/修改它们。

SET()似乎不是一个解决方案,它与外键/引用表不兼容。

所以起初,我正在考虑做一个TINYINT()专栏,我用这样的方式SET()111 (7)对于所有组,000 (0)对于无,001 (1)对于第一组,010 (2)对于第二组,等等。但是由于名称非常复杂,所以很混乱,仅此而已与外键兼容。

我读到我应该用 memberID 和 groupID 做一个第三张表“成员组”来加入我的两个表,但我不清楚它是如何工作的。

我的理解是,我将有一个包含成员和组 ID 的表,如下所示:

+----------+---------+
| memberID | groupID |
+----------+---------+
| 1        | 1       |
| 1        | 2       |
| 2        | 1       |
| 2        | 3       |
| 3        | 2       |
+----------+---------+

并结合 junction 我可以检索我想要的。这样对吗 ?否则有人可以解释我该怎么做吗?

我确切地说,我希望最终结果(在 sql 请求 + php 脚本之后)一个成员、他的属性和他所属的组在一行中(如SET()),甚至不属于任何组的成员.

4

2 回答 2

0

假设

drop table if exists mg;

drop table if exists m;
create table m (id int primary key, name varchar(3));
insert into m values
(1,'abc'),
(2,'def'),
(3,'ghi');

drop table if exists g;
create table g(id int primary key ,name varchar(3));
insert into g values
(1,'aaa'),
(2,'bbb'),
(3,'ccc');

create table mg
(memid int,grid int,
index fmid(memid,grid) ,
foreign key (memid) references m(id) on delete cascade,
foreign key (grid)  references g(id) on delete cascade
);
insert into mg values
(1,1),(1,2),(1,3),
(2,1),(2,3);

您可以加入 3 个表并使用 group_concat 或条件聚合生成结果。

MariaDB [sandbox]> select m.id,m.name, group_concat(g.name) groups
    -> from m
    -> join mg on mg.memid = m.id
    -> join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+-------------+
| id | name | groups      |
+----+------+-------------+
|  1 | abc  | aaa,bbb,ccc |
|  2 | def  | aaa,ccc     |
+----+------+-------------+
2 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select m.id,m.name,
    -> max(case when g.id = 1 then g.name else '' end) as group1,
    -> max(case when g.id = 2 then g.name else '' end) as group2,
    -> max(case when g.id = 3 then g.name else '' end) as group3
    -> from m
    -> join mg on mg.memid = m.id
    -> join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+--------+--------+--------+
| id | name | group1 | group2 | group3 |
+----+------+--------+--------+--------+
|  1 | abc  | aaa    | bbb    | ccc    |
|  2 | def  | aaa    |        | ccc    |
+----+------+--------+--------+--------+
2 rows in set (0.00 sec)

如果您希望不属于任何组的成员将联接更改为左联接。

ariaDB [sandbox]> select m.id,m.name, group_concat(g.name) groups
    -> from m
    -> left join mg on mg.memid = m.id
    -> left join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+-------------+
| id | name | groups      |
+----+------+-------------+
|  1 | abc  | aaa,bbb,ccc |
|  2 | def  | aaa,ccc     |
|  3 | ghi  | NULL        |
+----+------+-------------+
3 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select m.id,m.name,
    -> max(case when g.id = 1 then g.name else '' end) as group1,
    -> max(case when g.id = 2 then g.name else '' end) as group2,
    -> max(case when g.id = 3 then g.name else '' end) as group3
    -> from m
    -> left join mg on mg.memid = m.id
    -> left join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+--------+--------+--------+
| id | name | group1 | group2 | group3 |
+----+------+--------+--------+--------+
|  1 | abc  | aaa    | bbb    | ccc    |
|  2 | def  | aaa    |        | ccc    |
|  3 | ghi  |        |        |        |
+----+------+--------+--------+--------+
3 rows in set (0.00 sec)
于 2017-02-19T09:21:02.740 回答
0

我对这个问题感到半困惑,但我会尝试一下。

如果您有一个 Members 表,那么让 member_id 成为唯一的主键是有意义的。如果您想存储每个成员所在的组,只需在成员表中为每个组添加一个新列。

至于要赋予列的值,Group1您可以将它们设置为 ENUM('0','1') 或 ENUM('No','Yes') 或其他任何值,并将默认值设为负值(首先) 价值。Group2Group3

使用这个 db 结构,您不必在查询期间费心切分字符串——您只需编写 SELECT 或 WHERE 语句来指定适当的 Group 列值。

如果这不能直接回答,请澄清您的问题。

于 2017-02-19T04:36:48.417 回答