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有时有非常不同的语法。非常感谢您。这解决了我的问题。非常感谢你,特林科特。这解决了我的问题。