2

私は次のデータベーステーブルを持っています:

user
    int unsigned id
    varchar      login

group
    int unsigned id
    varchar      label

right
    int unsigned id
    varchar      label

user_group
    int unsigned userId
    int unsigned groupId

user_right
    int unsigned userId
    int unsigned rightId

group_right
    int unsigned groupId
    int unsigned rightId

権利は、user_rightまたはgroup_rightテーブルを使用して関連付けられている場合(それぞれ)、グループまたはユーザーに付与されていると見なされます。ログインからユーザーの権限を取得することになっている次のクエリがあります。

SELECT DISTINCT `R`.`id`,
                `R`.`label`
FROM `user` `U`,
     `right` `R`,
     `user_right` `UR`,
     `user_group` `UG`,
     `group_right` `GR`
WHERE (`U`.`id` = `UR`.`userId`
       AND `R`.`id` = `UR`.`rightId`
       OR `U`.`id` = `UG`.`userId`
       AND `UG`.`groupId` = `GR`.`groupId`
       AND `R`.`id` = `GR`.`rightId`)
  AND `U`.`login` = 'admin'

ユーザーが権利とグループに関連付けられている場合、クエリは機能し、権利を返します。ただし、ユーザーにグループがない場合、クエリは機能しません。未使用のテーブル(user_groupとgroup_rights)を削除すると、再び機能します。

これを回避するには、クエリに何を追加する必要がありますか?「ORsome_columnISNULL」のようなものを追加する必要がありますか?理由も説明していただければ幸いですので、二度とこの問題に遭遇することはありません。

前もって感謝します。

いくつかのサンプルデータ:

user (id, login)
1 'admin'

right (id, label)
1 'r1',
2 'r2',
3 'r3'

user_right (id, label)
1 1

読んでくれてありがとう :)

4

1 に答える 1

1

まず、暗黙的な結合を使用しています。クエリの記述方法では、これらはINNER JOINsです。適切な明示的結合を使用するようにクエリを変更LEFT JOINし、そこでsを使用する必要があります。このようなもの:

SELECT DISTINCT `R`.`id`,
                `R`.`label`
FROM `user` `U`
LEFT JOIN `user_right` `UR`
    ON `U`.`id` = `UR`.`userId`
LEFT JOIN `right` `R`
    ON `R`.`id` = `UR`.`rightId`
LEFT JOIN `user_group` `UG`
    ON `U`.`id` = `UG`.`userId`
LEFT JOIN `group_right` `GR`
    ON `UG`.`groupId` = `GR`.`groupId` AND `R`.`id` = `GR`.`rightId`
WHERE `U`.`login` = 'admin'
于 2012-11-14T13:54:26.200 に答える