web-dev-qa-db-ja.com

MySQL:テーブルの1つの行を他のテーブルの2つの行と結合する

私のMYSQLデータベースカンパニー。以下の図のように、2つのテーブルがあります(矢印は関係を示します)。

_  `users`                          `user_login`
+--------------+            +-----------------------+
| column_name  |            | column_name           |
+--------------+            +-----------------------+
| user_id      |<---|       | user_login_id         |
| first_name   |    |-------| user_id               |
| email_id     |            | user_name             |<---|
+--------------+            | created_by            |----|
                            +-----------------------+
_
  1. テーブル:_user_login_再帰的関連付けを使用して、従業員のユーザー名を上司が作成できるベースのアプリケーション。 _(created_by (1)- user_name (∞))_のようなものの自己関係。

  2. テーブル:usersには、各ユーザーの個人情報が含まれます(*または、user_loginテーブルの各ユーザー名について言います*)。

両方のテーブルで、すべてのフィールドはvarchar(64)です。また、_user_name_には一意性の制約があります。 (実際に使用しているデータベースは、列数と行数が多いので十分な大きさですが、有用な情報のみを入力しています

[クエリ]

私のクエリへの入力は_user_name_です。

クエリが必要ですuser_name値を指定すると、ユーザーとその直属の上司の両方について、ユーザーテーブル(_fist_name_および_email_id_)から情報が返されます。

ユーザーテーブルが次のとおりだとします。

_mysql> SELECT `user_id`, `first_name`, `email_id` FROM `users`;
+----------+------------+---------------------------+
| user_id  | first_name | email_id                  |
+----------+------------+---------------------------+
| 1        | Grijesh    | [email protected]    |
| 8        | Sumit      | [email protected]           |
| b        | OMD        | [email protected] |
+----------+------------+---------------------------+
3 rows in set (0.00 sec)
_

そしてuser_loginは

_mysql> SELECT user_login_id, user_id,  user_name , created_by FROM `user_login`;
+----------------+-----------+-----------+------------+
| user_login_id  | user_id   | user_name | created_by |
+----------------+-----------+-----------+------------+
| 13             | 1         | grijesh   | omdadmin   |
| 89             | 8         | sumit01   | grijesh    |
| bd             | b         | omdadmin  | SuperAdmin |
+----------------+-----------+-----------+------------+
3 rows in set (0.00 sec)
_

次に、入力user_name = 'grijesh'の出力の詳細は、omdおよびgrijeshに関するユーザーテーブルから取得する必要があります。

このために、私は以下のようなクエリを書きました(それはうまく機能しています):

_mysql> SELECT  `user_login`.`user_name`, 
               `users`.`first_name`, 
               `users`.`email_id` 
       FROM    `user_login`, `users` 
       WHERE   `user_login`.`user_id` = `users`.`user_id` AND
                (`user_login`.`user_name` = 'grijesh' 
                  OR 
                 `user_login`.`user_name` IN ( SELECT `created_by` 
                                               FROM `user_login`   
                                              WHERE `user_login`.`user_name` = 'grijesh' ));
_

その出力は次のようになります:

_+-----------+------------+---------------------------+
| user_name | first_name | email_id                  |
+-----------+------------+---------------------------+
| grijesh   | Grijesh    | [email protected]    |
| omdadmin  | OMD        | [email protected] |
+-----------+------------+---------------------------+
2 rows in set (0.06 sec)                              
_

[質問]

上記と同等のより効率的なクエリを使用できますか?結合を使用した解決策を考えてみましたが、user_loginの行の場合、ユーザーテーブルの2つの行と結合する必要があるため、このクエリでは私にとって困難です。

参加しようとしたができなかった。私がしたようにネストされたクエリの代わりに結合を使用したソリューションが必要です。

どんな助けや提案も大いに役立ちます。

1
Grijesh Chauhan

おそらく私はあなたの要求を誤解しているかもしれませんが、あなたの質問のテキストに基づいて十分に簡単に聞こえます:

SELECT
    U.first_name AS "User Name",
    U.email_id AS "User E-Mail Address",
    BossUser.first_name AS "Authorizing User Name"
    BossUser.email_id AS "Authorizing User E-Mail Address"
FROM
    user_login AS UL
    INNER JOIN users AS U ON UL.user_id = U.user_id
    LEFT JOIN  user_login AS BossLogin ON U.created_by = BossLogin.user_name
    LEFT JOIN  users AS BossUser ON BossLogin.user_id = BossUser.user_id

これにより、created_byを持たないユーザーも使用できます。そのフィールドがNOT NULLの場合、LEFT JOINsをINNER JOINに置き換えることができます。

2

uNIONステートメントを試す

SELECT  `user_login`.`user_name`, 
               `users`.`first_name`, 
               `users`.`email_id` 
FROM    `user_login`OIN `users` 
    ON   `user_login`.`user_id` = `users`.`user_id`
WHERE `user_login`.`user_name` = 'grijesh' 
UNION
SELECT  `user_login`.`user_name`, 
               `users`.`first_name`, 
               `users`.`email_id` 
FROM    `user_login`
JOIN `users` 
    ON   `user_login`.`user_id` = `users`.`user_id`
WHERE `user_login`.`user_login` in (SELECT  `Created_by`
FROM    `user_login`
WHERE `user_login`.`user_name` = 'grijesh')
1
HLGEM