我有一堆表,下面是表列表:
我将解释上面的表格字段和关系。
我的查询就在这里:
select acc_menu_items.* from acc_menu, acc_menu_items, acc_submenu, system_user, acc_user_role_map, acc_roles, acc_role_permission_map, acc_permission
where system_user.user_id=acc_user_role_map.user_id
and acc_user_role_map.ROLE_ID=acc_roles.id
and acc_roles.id=acc_role_permission_map.ROLE_ID
and acc_role_permission_map.PERMISSION_ID=acc_permission.id
and acc_permission.MENUITEM_ID=acc_menu_items.id
and acc_menu_items.menu_id=acc_menu.id
and acc_menu_items.SUBMENU_ID=acc_submenu.id
and system_user.USER_ID='userName' and acc_menu.menu_name='menuName';
我的问题是当我运行上面的查询时显示为空。
在该查询中删除表名“acc_submenu”和“acc_menu_items.SUBMENU_ID = acc_submenu.id”
我收到数据很好,如果我把子菜单列表也变空了。
如果有什么不清楚,我会上传完整的数据。
任何人都有任何想法?
找到下面的图片链接
http://www.4shared.com/photo/2Ml256my/Untitled-1-copy.html
我的查询是:
select acc_menu_items.* from acc_menu, acc_menu_items, acc_submenu, system_user, acc_user_role_map, acc_roles, acc_role_permission_map, acc_permission
where system_user.user_id=acc_user_role_map.user_id
and acc_user_role_map.ROLE_ID=acc_roles.id
and acc_roles.id=acc_role_permission_map.ROLE_ID
and acc_role_permission_map.PERMISSION_ID=acc_permission.id
and acc_permission.MENUITEM_ID=acc_menu_items.id
and acc_menu_items.menu_id=acc_menu.id
and system_user.USER_ID='setupadmin' and acc_menu.menu_name='Administrator';
上面的查询是获取数据,当我用'MainMenu'替换'Administrator'时,它不起作用,请解释一下是什么问题?
我该怎么办?有什么想法吗?
答案 0 :(得分:2)
使用显式连接语法的第二个查询:
select ami.*
from acc_submenu
-- MISSING JOIN CONDITION
join acc_roles ar
-- MISSING JOIN CONDITION
join acc_user_role_map aurm
on aurm.role_id = ar.id
join system_user su
on su.user_id = aurm.user_id
join acc_role_permission_map arpm
on ar.id = arpm.role_id
join acc_permission ap
on arpm.permission_id = ap.id
join acc_menu_items ami
on ap.menuitem_id = ami.id
join acc_menu am
on ami.menu_id = am.id
where su.user_id = 'setupadmin'
and am.menu_name = 'Administrator'
正如您所看到的,您有一些缺失的加入条件,这意味着您正在acc_submenu
和acc_roles
上进行Cartesian join。我认为这是无意的......
使用显式连接语法的第一个查询:
select ami.*
from system_user su
join acc_user_role_map aurm
on su.user_id = aurm.user_id
join acc_roles ar
on aurm.role_id = ar.id
join acc_role_permission_map arpm
on ar.id = arpm.role_id
join acc_permission ap
on arpm.permission_id = ap.id
join acc_menu_items ami
on ap.menuitem_id = ami.id
join acc_menu am
on ami.menu_id = am.id
join acc_submenu as
on ami.submenu_id = as.id
where su.user_id = 'userName'
and am.menu_name = 'menuName';
这一切似乎都过于复杂。如果我们使用您发布的数据向后工作;你想要acc_menu_items
:
menu_name = 'MainMenu'
表中的所有内容
那将是:
select ami.*
from acc_menu am
join acc_menu_items ami
on am.id = ami.menu_id
你也想把它限制在system_user.user_id = 'setupadmin'
,这对我来说是不幸的,因为我现在要写很多东西......顺便说一下,没有真正的理由去system_user
,除非你希望所有事情都在name = 'pradeep'
。
在我得到的时候建立一个联接:
select ami.*
from acc_user_role_map aurm
join acc_role_permission_map arpm
on aurm.role_id = arpm.role_id
join acc_permission ap
on arpm.permission_id = ap.id
-- Now I'm stuck as there-s nothing else to join to
-- however, for the sake of argument let-s assume that acc_permission
-- does have menuitem_id and that that number is one of those
-- specified
join acc_menu_items ami
on ap.menuitem_id = ami.id
join acc_submenu as
on ami.submenu_id = as.id
join acc_menu am
on am.id = as.menu_id
where aurm.user_id = 'setupadmin'
and am.menu_name = 'MainMenu'
正如您所看到的,连接较少,这使得它更清晰。还有一个假设我无法验证。我假设在menuitem_id
中存在acc_permission
的1123,1125,1127或1129。
但是还有另一个微妙的区别。我首先加入acc_submenu
然后加入acc_menu
以获取查询。这也改变了连接条件;这不再是:
on acc_menu_items.menu_id = acc_menu.id
但
on acc_menu.id = acc_submenu.menu_id
这就是你没有得到结果的原因;您的加入查询不正确。
这引出了我几点:
由于您的第二个查询演示不使用显式连接语法是一种容易出错的方法。 不值得使用隐式连接语法;特别是当您的查询有很多连接或复杂时。几十年来它们一直是SQL标准,所以你应该使用它们。
创建复杂查询时,如果一次构建一层,通常会更容易。这意味着您可以验证在每个阶段是否返回了您期望的结果。如果出错,您可以轻松查明发生的位置。
还有一些友好的建议,你可以随意忽略或不遵守:
您的架构过于复杂;特别是在菜单表周围。特别令人不安的是acc_menu_items
之后的联接必须是两个不同表中的一个,你不知道哪个。如果可以简化这个,请做。例如,通过向parent_id
添加acc_menu
并在此处移动子菜单。然后,您可以删除acc_menu_items
上的额外列。
答案 1 :(得分:0)
没有太多想法:你的线阅读
and acc_menu_items.SUBMENU_ID=acc_submenu.id
表示acc_menu_items.SubMenu_ID在Acc_submenu.id中有相应的条目。你有支持该断言的数据吗?
含义:在ACC_MENU_ITEMS.SubMenu_ID中,您有一条名为“1”的记录 在Acc_SubMenu.id中你也有一个相同数据类型的记录,如果没有,那么你的逻辑是否有缺陷。根据你的测试,这可能是问题