查询6个表,有更好的方法吗?

时间:2012-04-22 16:18:32

标签: mysql sql

我所做的是,我希望每个用户都拥有自己的“独特”编号系统。我没有自动将项目编号递增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

users_items

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

users_rooms

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

users_category

|  id  |  room_name  |
----------------------
|   1  |   antiques  |
|   2  |   appliance |
|   3  |   sporting goods |

users_map_category

|  map_room_id  |  map_user_id  |  unique_category_id  |
----------------------------------------------------
|       1       |       1       |          1       |
|       2       |       1       |          2       |
|       3       |       2       |          1       |

1 个答案:

答案 0 :(得分: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。在这种情况下,您可能希望将其他WHERE条款移至JOIN条件,因为它会更改结果。