2

こんにちは、クエリにテーブル user のすべてのレコードを入力し、それぞれに他の 2 つのテーブル (user_permission & permission) からのアクセス許可を確認させようとしています。

私が持っている現在のクエリはこれです:

SELECT user.id, user.email,  
CONCAT(' ', user.name, user.username) AS theNameUserName,
IF(user.opted_in = 0, 'NO', 'YES') AS optedIn  
FROM user AS user, user_permission AS userPerm
INNER JOIN permission AS Perm ON Perm.id = userPerm.permission_id;

これは問題なく実行されますが、何度も同じデータしかありません。返されるレコードは 1000 件だけで、各 person が 3 回複製されますuser テーブル470 人のユーザーがいるので、470 レコードすべてを返す必要があります。

それを行うには、上記のクエリに対して何をする必要がありますか? User.idはuser_permission user_idと一致します。

user_permission テーブルのレイアウト:

  user_id  permission_id
       1        1
       2        3
       3        3
       8        4
       9        4
      10        4
      11        4
      12        4
      13        4
       ....etc etc

権限テーブル:

   id            name
    4      registered users
    3      editor
    2      developer
    1      administrator
    5      registered builders

ユーザーテーブル:

   id      name         email                username           opted_in
   11   David Dxxxx     dxxxxx@exxxx.com    dxxxxxx@exxxxx.com      0
   12   Michael Lxx     sx@sprintmail.com   sxxxxxx@sxxxxx.com      0
   13   Jon Fxxxxxx     jxxxxxxx@xxx.com    jxxxxxx@sxxxxx.com      0
        etc etc .......
4

1 に答える 1

2

暗黙的な(コンマで区切られた)INNER JOINものと明示的なものの異常な組み合わせがあり、最終的には結合userする条件がないuser_permissionため、2つのデカルト積が得られます。あなたJOINのは次のようになります:

SELECT
  user.id,
  user.email,  
  CONCAT_WS(' ', user.name, user.username) AS theNameUserName,
  IF(user.opted_in = 0, 'NO', 'YES') AS optedIn  
FROM 
  user
  LEFT JOIN user_permission AS userPerm ON user.id = userPerm.user_id
  INNER JOIN permission AS Perm ON Perm.id = userPerm.permission_id;

関連する権限を持たないユーザーをリストするために、 LEFT JOINbetweenuserとtoを置き換えました。結果から除外する必要がある場合は、代わりに使用してください。user_permissionNULLINNER JOIN

CONCAT()また、最初にスペースがあるので、私はあなたを置き換えましCONCAT_WS()た-あなたは2つを分離するのではなく、ストリングの前にスペースを貼り付けていたでしょう(それがあなたが意図したものである場合)。

最後の注意:あなたのIF()条件はSELECTMySQLと他のいくつかのRDBMSでうまく機能しますが、その最も移植性の高いバージョンではCASE代わりに次のものを使用します。

CASE WHEN user.opted_in = 0 THEN 'NO' ELSE 'YES' END AS theNameUserName

...これを別のRDBMSで実行する必要があると予想される場合の単なる提案です。

于 2012-08-21T20:39:12.137 に答える