mysql - 跨 6 个表查询,是否有更好的方法?

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

用户项目

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

相关文章:

Python MySQLdb : creating database and filling table

php - 有没有办法在模式关闭之前(在计时器 4 秒内)将信息保存到 mysql,而不使用提交按钮

mysql - MySQL的auto_increment步长是如何确定的

c# - 关键字 'add' 附近的语法不正确

php - SELECT 语句给出 fatal error : Invalid parameter number in

SQL 查询数学体操

mysql - SQL Like 在 "/"上崩溃

php - 命令在 php 中恢复 mysql 数据库备份

mysql - 选择DML还是DDL?

sql - 奇怪的 Oracle SQL "Invalid Identifier"错误