我所做的是,我希望每个用户都有自己的“唯一”编号系统。我没有将项目编号自动递增 1,而是让 Bob 的第一个项目从 #1 开始,Alice 的编号也从 #1 开始。房间和类别也是如此。我通过为项目、房间和类别创建“映射”表来实现这一点。
下面的查询有效,但我知道它绝对可以重构。我在每个表中都有主键(在“ids”上)。
SELECT unique_item_id as item_id, item_name, category_name, item_value, room_name
FROM
users_items, users_map_item, users_room, users_map_room, users_category, users_map_category
WHERE
users_items.id = users_map_item.map_item_id AND
item_location = users_map_room.unique_room_id AND
users_map_room.map_room_id = users_room.room_id AND
users_map_room.map_user_id = 1 AND
item_category = users_map_category.unique_category_id AND
users_map_category.map_category_id = users_category.category_id AND
users_category.user_id = users_map_category.map_user_id AND
users_map_category.map_user_id = 1
ORDER BY item_name
用户项目
| id | item_name | item_location |item_category |
--------------------------------------------------------
| 1 | item_a | 1 | 1 |
| 2 | item_b | 2 | 1 |
| 3 | item_c | 1 | 1 |
users_map_item
| map_item_id | map_user_id | unique_item_id |
----------------------------------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
用户房间
| id | room_name |
----------------------
| 1 | basement |
| 2 | kitchen |
| 3 | attic |
users_map_room
| map_room_id | map_user_id | unique_room_id |
----------------------------------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
用户类别
| id | room_name |
----------------------
| 1 | antiques |
| 2 | appliance |
| 3 | sporting goods |
用户 map 类别
| map_room_id | map_user_id | unique_category_id |
----------------------------------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
最佳答案
使用明确的 JOIN 条件重写您的查询使其更具可读性(同时这样做)。
SELECT mi.unique_item_id AS item_id
, i.item_name
, c.category_name
, i.item_value
, r.room_name
FROM users_map_item mi
JOIN users_items i ON i.id = mi.map_item_id
JOIN users_map_room mr ON mr.unique_room_id = i.item_location
JOIN users_room r ON r.room_id = mr.map_room_id
JOIN users_map_category mc ON mc.unique_category_id = i.item_category
JOIN users_category c ON (c.user_id, c.category_id)
= (mc.map_user_id, mc.map_category_id)
WHERE mr.map_user_id = 1
AND mc.map_user_id = 1
ORDER BY i.item_name
结果不变。查询计划应该相同。我认为没有办法进一步改进查询。
如果要在结果中保留右侧找不到匹配行的行,则应使用 LEFT [OUTER] JOIN
而不是 [INNER] JOIN
table 。在这种情况下,您可能希望将额外的 WHERE
子句移动到 JOIN
条件,因为它会改变结果。
关于mysql - 跨 6 个表查询,是否有更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10269693/