0

私はたくさんのテーブルを持っています、以下はテーブルリストです:

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

明示的な結合構文を使用した 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_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'.

一度に1つの結合を構築すると、次のようになります。

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に1123、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

これが、結果が得られない理由です。結合クエリが正しくありません。


これは私をいくつかのポイントに導きます:

  • 2 番目のクエリが示すように、明示的な結合構文を使用しないと、エラーが発生しやすくなります。暗黙の結合構文を使用する価値はありません。特に、クエリに多くの結合がある場合や複雑な場合。これらは数十年前から SQL の標準となっているため、それらを使用する必要があります。

  • 複雑なクエリを作成する場合、一度に 1 つのレイヤーを作成すると簡単になります。これは、期待する結果が各段階で返されているかどうかを検証できることを意味します。間違えた場合は、どこで発生したかを簡単に特定できます。

そして、あなたが好きなように無視するかどうかにかかわらず、いくつかの友好的なアドバイス:

スキーマが複雑すぎます。特にメニュー表周り。特に当惑するのは、その後の結合acc_menu_itemsが 2 つの異なるテーブルのいずれかである必要があり、どちらがどちらかわからないという事実です。これを単純化できる場合は、そうしてください。たとえば、サブメニューをここに追加して移動しますparent_idacc_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 に答える