Mysql 连接3个表,第二个表上限制1

Mysql 连接3个表,第二个表上限制1,mysql,sql,Mysql,Sql,我有三个表,个人,公司和任务 人们在不同的公司里执行不同的任务 我想要的是所有persons表的列表、他们在tasks中的最后一个任务以及他们执行该任务时的公司名称。最近的任务可以是最新的任务\日期或更高的id。任务,它具有相同的结果 表人员: | id | Name | | 1 | Person 1 | | 2 | Person 2 | | 3 | Person 3 | | 4 | Person 4 | 表公司: ————————————————

我有三个表,
个人
公司
任务

人们在不同的公司里执行不同的任务

我想要的是所有persons表的列表、他们在tasks中的最后一个任务以及他们执行该任务时的公司名称。最近的任务可以是最新的任务\日期或更高的id。任务,它具有相同的结果

人员

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

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

————————————————————————————————————————————————————————————————————
| 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
我认为结果是可以的,但是缺少了一些人员,因为使用了
内部连接
(我有一些人员没有关联任何任务)。我尝试将
内部连接
更改为
左连接
,但结果不正常

感谢您的帮助。

尝试以下方法:

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
试试这个:

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

您应该做的是将最新的任务/公司数据设置为一个内联视图,然后从person表左连接到该视图

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

您应该做的是将最新的任务/公司数据设置为一个内联视图,然后从person表左连接到该视图

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

根据您的查询,我只需做一个简单的修改:

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
s。这是您的查询所需的唯一更改。

对于您的查询,我只需做一个简单的修改:

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
s。这是您的查询所需的唯一更改。

John Wyss给出的答案有点小改动,这个查询只是澄清了他提供的答案。。。希望这也能有所帮助

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

John Wyss给出的答案中有一点小改动,这个问题只是澄清了他提供的答案。。。希望这也能有所帮助

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

解决方案是在
左联接中
,但您需要首先联接子查询,然后才联接
任务
表,否则您会得到太多的结果(我还修复了查询中的一些输入错误):

输出与您在问题中列出的完全相同:

| id |     Name | company_name |
|----|----------|--------------|
|  1 | Person 1 |    Company 4 |
|  2 | Person 2 |    Company 1 |
|  3 | Person 3 |       (null) |
|  4 | Person 4 |    Company 2 |

这里有一个

解决方案是在
左连接中
,但是您需要先连接子查询,然后才连接
任务
表,否则您会得到太多的结果(我还修复了查询中的一些输入错误):

输出与您在问题中列出的完全相同:

| id |     Name | company_name |
|----|----------|--------------|
|  1 | Person 1 |    Company 4 |
|  2 | Person 2 |    Company 1 |
|  3 | Person 3 |       (null) |
|  4 | Person 4 |    Company 2 |

下面是一个

您可以尝试左外部联接吗?为什么左联接的结果不正常?请标记您正在使用的DBMS。MySQL和SQL Server有时有非常不同的语法。您可以尝试左外部连接吗?为什么左连接的结果不正常?请标记您正在使用的DBMS。MySQL和SQL Server有时有非常不同的语法。非常感谢您。这解决了我的问题。非常感谢你,特林科特。这解决了我的问题。