2016-04-10 23 views
1

私は仕事のために「仕事」テーブルを持っています。 システムには2種類のユーザーがあります。「Admin」と「Agent」はどちらも「Admin」と「Agents」という異なるテーブルに格納されています。Mysql IF条件付き同じテーブルを2回左に結合する

**Table Admin** 
admin_id   | 1 
admin_name   | John 
admin_surname  | Doe 

**Table Agents** 
agent_id   | 1 
agents_name  | Sally 
agents_surname  | Zoe 

また、他のユーザーのタスクやリクエストを追加できる「タスク」テーブルがあります。

**Table Tasks** 
task_id   | 1 
task_inquirer_type | (1 if Admin, 2 if Agent) 
task_inquirer_id | ID from related user table 
task_assigned_type | (1 if Admin, 2 if Agent) 
task_assigned_id | ID from related user table 
task_text   | text 

私は、照会者と割り当てられたユーザーの名前と姓を取得するために管理者とエージェントのテーブルを結合して1 MySQLのクエリのすべてのレコードを取得しようとしています。

以下のSQLを使用すると、1人のユーザーのレコードを取得できます。

SELECT tasks.*, 
    admins.admin_name as inquirer_name, admins.admin_surname as inquirer_surname 

    FROM tasks 

    INNER JOIN admins on admins.admin_id = tasks.task_inquirer_id 
    WHERE tasks.task_inquirer_type = 1 
    AND task_assigned_id = 1 AND task_assigned_type = 1 


    UNION 


    SELECT tasks.*, 
    agents.agent_name as inquirer_name, agents.agent_surname as inquirer_surname 

    FROM tasks 

    INNER JOIN agents on agents.agent_id = tasks.task_inquirer_id 
    WHERE tasks.task_inquirer_type = 2 
    AND task_assigned_id = 1 AND task_assigned_type = 1 

このクエリでは、ID(1)のAdmin(1)ユーザーに割り当てられたすべてのレコードを取得できます。しかし、私はすべてのレコードをリストし、すべての名前を "照会者"と "割り当てられた"リストに入れたい別のページを作っています。私は下の質問を試したが、何とかそれは私に間違った名前を与えたが、残りは大丈夫である。

SELECT tasks.*, 
inquirer.admin_name as inquirername, inquirer.admin_surname as inquirersurname, 
assigned.admin_name as assignedname, assigned.admin_surname as assignedsurname 

FROM tasks 

INNER JOIN admins AS inquirer on inquirer.admin_id = tasks.task_inquirer_id 
INNER JOIN admins AS assigned on assigned.admin_id = tasks.task_assigned_id 

WHERE tasks.task_inquirer_type = 1 


UNION 


SELECT tasks.*, 
inquirer.agent_name as inquirername, inquirer.agent_surname as inquirersurname, 
assigned.agent_name as assignedname, assigned.agent_surname as assignedsurname 

FROM tasks 

INNER JOIN agents AS inquirer on inquirer.agent_id = tasks.task_inquirer_id 
INNER JOIN agents AS assigned on assigned.agent_id = tasks.task_assigned_id 

WHERE tasks.task_inquirer_type = 2 

どのように質問を処理する必要がありますか?私は両方のタイプを探す必要があることを知っています。「WHERE tasks.task_inquirer_type = 1 or 2」という1つのタイプだけではありません。 「WHERE tasks.task_assigned_type = 1 or 2」も問合せに含まれていなければなりません。

ありがとうございました。それをやっての

答えて

1

あなたのデータモデルを変更する必要があります。つまり、データの一貫性を保証することはできません。 task_inquirer_idtask_assigned_idには任意の数値を入れることができます。 DBMSは、たとえばエージェントテーブルにエージェントIDが実際に存在することを制御するのを手助けすることはできません。

テーブルadminagentが例の場合と非常によく似ている場合は、その人物がエージェントか管理者かを示すフラグを付けてpersonテーブルにします。

 
task_id (PK) 
task_inquirer_person_id (FK not nullable) 
task_assigned_person_id (FK not nullable) 

personテーブルへの外部キーで次のようにあなたはtasksテーブルを変更すると思います。管理者またはエージェントがリンクされたレコードによって暗黙的に指定されるかどうか。

テーブルadminagentは非常に異なる場合には、これだけのようなあなたのtasksテーブルを変更します。

 
task_id (PK) 
task_inquirer_admin_id (FK nullable) 
task_inquirer_agent_id (FK nullable) 
task_assigned_admin_id (FK nullable) 
task_assigned_agent_id (FK nullable) 

は、常に一つだけ質問者を確保するために示すように、メインのテーブルに外部キーを追加し、制約を追加し、 1人の担当者がレコードに設定されます。

テーブルを照会する方がはるかに簡単です。

+0

デザインを変更したほうが良いと私は同意しますが、データの一貫性を保証することはできません。トリガーを使用することができます。 – maraca

+0

ありがとうございます。私はすでに過去数年間でうまく機能していた単一のユーザーテーブルバージョンと別のタスクテーブルを使用していますが、管理者、エージェント、ユーザーデータベースを別々にしなければなりませんでした。だから私はそれらを分離しておく必要があります。 – hakanerenler

+1

ご覧のとおり、 'admin'テーブルと' agent'テーブルが非常に異なる場合に、 'tasks'テーブルを変更する方法についてのアドバイスもあります。 –

0

一つの方法(すべてに参加し、条件付きのアプローチを選択し、あなたは、サブセレクトで仕事ができる):私の意見で

SELECT 
    t.*, 
    CASE WHEN b1.agent_id IS NULL THEN a1.admin_name ELSE b1.agent_name END inquirername, 
    CASE WHEN b1.agent_id IS NULL THEN a1.admin_surname ELSE b1.agent_surname END inquirersurname, 
    CASE WHEN b2.agent_id IS NULL THEN a2.admin_name ELSE b2.agent_name END assignedname, 
    CASE WHEN b2.agent_id IS NULL THEN a2.admin_surname ELSE b2.agent_surname END assignedsurname 
FROM 
    tasks t LEFT JOIN 
    admin a1 ON a1.admin_id = t.inquirer_id AND t.inquirer_type = 1 LEFT JOIN 
    admin a2 ON a2.admin_id = t.assigned_id AND t.assigned_type = 1 LEFT JOIN 
    agents b1 ON b1.agent_id = t.inquirer_id AND t.inquirer_type = 2 LEFT JOIN 
    agents b2 ON b2.agent_id = t.assigned_id AND t.assigned_type = 2 
; 
関連する問題