0

我有一堆表格,下面是表格列表:

  • 系统_用户
  • Acc_Roles
  • Acc_User_role_map
  • Acc_Permission
  • Acc_Role_Permission_Map
  • Acc_Menu_Items
  • Acc_SubMenu
  • Acc_Menu

我将解释上面的表格字段和关系。

我的查询在这里:

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

上面的查询正在获取数据,当我将 'Administrator' 替换为 'MainMenu' 时,它不起作用,请解释是什么问题?

我能做些什么?有任何想法吗?

4

2 回答 2

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'

如您所见,您缺少一些连接条件,这意味着您正在对and进行笛卡尔连接。我想这是无意的...acc_submenuacc_roles

您使用显式连接语法的第一个查询:

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_id1123、1125、1127 或 1129 中的a acc_permission

不过,还有另一个细微的差别。我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_idtoacc_menu并将子菜单移动到此处。然后,您可以删除 上的额外列acc_menu_items

延伸阅读:

于 2012-06-11T21:09:47.920 回答
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 中,您还有一个名为“1”的相同数据类型的记录,如果没有,那么您的逻辑是否有缺陷。根据您的测试,这可能是问题所在

于 2012-06-10T19:01:59.547 回答