2016-03-23 24 views
0

私は3つのテーブルpersons,companiesおよびtasksを持っています。2つ目のテーブルに3つのテーブルLIMIT 1を結合します。

人物は異なる会社で異なる仕事をします。

私が望むのは、すべての人物テーブルのリスト、タスクで最後に実行したタスク、そしてそのタスクを実行するときの会社の名前です。最新のタスクは最新のtask_dateまたはそれ以上のid.taskである可能性がありますが、同じ結果が得られます。

persons

表:

| id | Name  | 
| 1 | Person 1 | 
| 2 | Person 2 | 
| 3 | Person 3 | 
| 4 | Person 4 | 

companies

————————————————————— 
| id | company | 
————————————————————— 
| 1 | Company 1 | 
| 2 | Company 2 | 
| 3 | Company 3 | 
| 4 | Company 4 | 
————————————————————— 

tasks

———————————————————————————————————————————————————————————————————— 
| id | task_name | task_date | id_persons | id_companies | 
———————————————————————————————————————————————————————————————————— 
| 1 | Task 1  | 2015-01-02 |  1  |   3 | 
| 2 | Task 2  | 2016-03-02 |  1  |   4 | 
| 3 | Task 3  | 2016-06-04 |  2  |   1 | 
| 4 | Task 4  | 2016-01-03 |  4  |   2 | 

結果は、このようなテーブルであるべきです

| persons.id | persons.name | company.name | 
|  1  | Person 1  | Company 4 | 
|  2  | Person 2  | Company 1 | 
|  3  | Person 3  |    | 
|  4  | Person 4  | Company 2 | 
—————————————————————————————————————————————————— 

私はこのクエリがあります:

SELECT t.id id_t, t.id_companies t_id_companies, c.company_name , p.* 
FROM persons p 
INNER JOIN tasks t ON t.id_persons = p.id 
INNER JOIN 
     (
      SELECT id_persons, MAX(id) max_id 
      FROM tasks 
      GROUP BY id_persons 
     ) b ON t.id_persons = b.id_persons AND t.id = b.max_id 
INNER JOIN companies c ON c.id = t.companies.id 
WHERE p.deleted = 0 

私は結果がOKだと思いますが、しかし、そこにいくつかの行方不明者、なぜならINNER JOINの使用(Iは、関連するすべてのタスクを持っていない者を持っています)。 INNER JOINLEFT JOINに変更しようとしましたが、結果はOKではありませんでした。

何か助けていただければ幸いです。

+3

のですか? – trincot

+0

左外部結合を試みることができますか? –

+0

なぜ、左結合の結果はOKではありませんか? –

答えて

1

ソリューションはLEFT JOIN中ですが、必要に役立つことを願っています

SELECT  p.id persons_id, p.name persons_name, c.company_name 
FROM  persons p 
LEFT JOIN 
     (
      SELECT id_persons, MAX(id) max_id 
      FROM tasks 
      GROUP BY id_persons 
     ) b ON p.id = b.id_persons 
LEFT JOIN tasks t ON t.id_persons = p.id AND t.id = b.max_id 
LEFT JOIN companies c ON c.id = t.id_companies 
WHERE  p.deleted = 0 
ORDER BY 1 

出力は、あなたの質問に記載されているように正確である:

最初のサブクエリに参加し、だけにして tasks表は、そうでなければ、あまりにも多くの結果を得る(また、私はあなたのクエリ内のいくつかのタイプミスを修正します)ここでは
| id |  Name | company_name | 
|----|----------|--------------| 
| 1 | Person 1 | Company 4 | 
| 2 | Person 2 | Company 1 | 
| 3 | Person 3 |  (null) | 
| 4 | Person 4 | Company 2 | 

はどのSQLエンジンfiddle

+0

ありがとう、トリンコット。それが私の問題を解決しました。 –

0

この試してみてください:あなたは何をすべき

SELECT p.id, p.name, c.name 
FROM persons p 
LEFT JOIN ((
     SELECT id_persons, id_companies, MAX(id) max_id 
     FROM tasks 
     GROUP BY id_persons, id_companies 
    ) t INNER JOIN companies c ON c.id = t.companies.id) 
ON t.id_persons = p.id 
WHERE p.deleted = 0 
1

は、最新のタスク/企業データにインライン・ビューを作成し、左の人のテーブルからそれに参加するんです。

SELECT * 
FROM persons p 
LEFT JOIN (
    SELECT * FROM tasks t 
    INNER JOIN companies c ON c.id = t.companies.id 
    WHERE t.id IN (SELECT max(id) FROM tasks GROUP BY id_persons) 
) combined_tasks 
ON p.id = combined_tasks.id 
WHERE p.deleted = 0 
0

はあなたのクエリを考えると、私はちょうど簡単な変更を行うだろう。つまり

SELECT t.id id_t, t.id_companies t_id_companies, c.company_name , p.* 
FROM persons p LEFT JOIN 
    tasks t 
    ON t.id_persons = p.id LEFT JOIN 
    (SELECT id_persons, MAX(id) as max_id 
     FROM tasks 
     GROUP BY id_persons 
    ) b 
    ON t.id_persons = b.id_persons AND t.id = b.max_id LEFT JOIN 
    companies c 
    ON c.id = t.companies.id 
WHERE p.deleted = 0; 

は、すべてJOIN sがLEFT JOIN秒でなければなりません。これがクエリに必要な唯一の変更です。ジョンWyssのによって与えられた答えで

0

少しの微調整は、このクエリは、ちょうど彼が提供する答えを明確に...これは、同様

SELECT p.*, combined_tasks.companyname 
FROM person p 
LEFT JOIN (
    SELECT t.personid as personid, c.name as companyname FROM task t 
    INNER JOIN company c ON c.id = t.companyid 
    WHERE t.id IN (SELECT max(id) FROM task GROUP BY personid) 
) combined_tasks 
ON p.id = combined_tasks.personid 
関連する問題