0

我正在尝试加深对 MySQL 的了解,以及关系如何在数据库中的几个不同表之间起作用。我了解主键和外键以及它们在表中的工作方式。

我拥有的是一个我正在玩的测试数据库peoplehats以及不同帽子和人之间的关系。这是我到目前为止在我的测试数据库中的内容:

| 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 表中的不同帽子,并将它们与表中不同人的关系保存在hats_collection仅使用person_idand的表中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;

这是返回一个空集。

我的问题是:

  1. 我将如何更改我的查询以获得哪些人拥有哪些帽子的正确结果?
  2. 这是我为这样的事情设置表格的方式吗?有没有更简单/更有效的方法?

编辑

抱歉,我发布的查询有效。它返回一个空集,因为 id 为 1 的人没有任何帽子,但这产生了一个新问题:

  1. 这是编写此查询的最佳方式吗?

我关于成为最有效的方法的问题仍然存在。

4

3 回答 3

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部分。

于 2013-05-29T18:49:03.803 回答
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上面的代替inner's。

于 2013-05-29T18:51:02.243 回答
1

删除 select 语句中的 WHERE 子句,以显示人们戴着帽子。根据样本数据,person_id = 1 没有帽子。

于 2013-05-29T18:48:43.883 回答