我正在努力提高我对MySQL的了解,以及如何在数据库中的几个不同表之间建立关系。我理解主键和外键以及它们在表中的工作方式。
我所拥有的是一个测试数据库,我正在玩满people
,hats
以及不同帽子与人之间的关系。以下是我目前在测试数据库中的内容:
| Tables_in_test |
+-----------------+
| hats |
| hats_collection |
| people |
+-----------------+
我的people
表格如下:
+-----------+---------+
| person_id | fname |
+-----------+---------+
| 1 | Sethen |
| 2 | Michael |
| 3 | Jazmine |
+-----------+---------+
我的hats
表格如下:
+--------+----------+
| hat_id | hat |
+--------+----------+
| 1 | Awesome |
| 2 | Kick Ass |
| 3 | Bowler |
| 4 | Fedora |
+--------+----------+
最后我的hats_collection
表看起来像这样:
+-----------+--------+
| person_id | hat_id |
+-----------+--------+
| 2 | 1 |
| 2 | 4 |
| 3 | 2 |
+-----------+--------+
基本上,我存储了帽子表中可能存在的所有不同的帽子,并将他们的关系保存在hats_collection
表格中仅使用person_id
和hat_id
的不同人
虽然我确定如何正确设置所有这些表并插入数据,但我不确定如何编写查询以显示hats_collection
表中的数据以显示用户名和哪个帽子他们有。
这是我到目前为止所做的:
SELECT people.fname, hats.hat
FROM people
INNER JOIN hats
INNER JOIN hats_collection
ON hats_collection.person_id = people.person_id AND hats_collection.hat_id = hats.hat_id
WHERE people.person_id = 1;
返回一个空集。
我的问题是这些:
修改
道歉,我发布的查询有效。它返回一个空集,因为id为1的人没有任何帽子,但这产生了一个新问题:
关于成为最有效的方法的问题仍然存在。
答案 0 :(得分:2)
id = 1的人没有任何帽子所以这很好。
如果您想要显示人物,即使他们没有任何帽子,您也必须使用LEFT JOIN
SELECT people.fname, GROUP_CONCAT(hats.hat) AS hats
FROM people
LEFT JOIN hats_collection ON hats_collection.person_id = people.person_id
LEFT JOIN hats ON hats_collection.hat_id = hats.hat_id
GROUP BY people.person_id;
注意我如何逻辑地重新排序连接表并将每个相关的连接条件放到它自己的连接表ON
部分。
答案 1 :(得分:1)
删除select语句中的WHERE子句以向人们展示他们的帽子。根据样本数据,person_id = 1没有帽子。
答案 2 :(得分:1)
ON的标准应该在每个连接上,否则你得到所谓的交叉连接所有人的记录到帽子的所有记录,这不是你想要的。
SELECT people.fname, hats.hat
FROM people
INNER JOIN hats_collection
ON hats_collection.person_id = people.person_id
INNER JOIN hats
ON hats_collection.hat_id = hats.hat_id
WHERE people.person_id = 1;
表格是在“正常/通常的做法”中设计的
现在,如果你想要所有人,不管他们是否有帽子......使用LEFT JOIN
代替上面的内部。