MYSQL-按分组并选择最高结果并使用JOIN?

时间:2019-01-09 13:11:49

标签: mysql sql

我有2个SQL表,我需要从第二个表中获取最高的时间戳,并且该时间戳必须在一定范围内。

Table: Projects 
ID,Name,invoiceTotal,department
1,Project1,100,1
2,Project2,200,3
3,Project3,300,2
4,Project4,100,2
5,Project5,400,1


Table: Manning
ProjectID,timestamp
1,1547038287
1,1515558287
1,1501118287
5,1471118287
5,1481118287

我一直在使用PHP首先运行一个具有内部联接的查询,以便我可以提取两个表数据。

SELECT
project.ID,
project.name,
project.invoiceTotal,
manning.timestamp
FROM
manning
INNER JOIN projects ON project.ID = manning.ProjectID
WHERE
project.department = 1 AND
manning.timestamp BETWEEN 1547038287 AND 1301118287
ORDER BY
manning.timestamp ASC

然后,我遍历PHP,并运行过程代码对数据进行排序,然后将其显示。问题是它很慢,而且绝对不是最有效的方法。

因此,在此示例数据中,我希望得到结果:

1,Project1,100,1547038287
5,Project5,400,1481118287

我一直在尝试使用“分组依据”,但是,如果人员配置表的顺序不正确,则不会得到正确的结果。

感谢您的帮助。我曾尝试使用sqlfiddle.com,但现在看来对我来说很沮丧:(

3 个答案:

答案 0 :(得分:0)

不要加入所有人员配置行,而只能加入每个项目的最新行:

select
  p.ID,
  p.name,
  p.invoiceTotal,
  m.max_timestamp
from projects p
join
(
  select projectid, max(timestamp) as max_timestamp
  from manning
  where timestamp between 1301118287 and 1547038287
  group by projectid
) m on m.projectid = p.id
where p.department = 1;

这不仅是编写此查询的一种简便方法,还是一种非常有效的方法。当您只对其中的几个感兴趣时,为什么还要加入所有记录?不要产生巨大的中间结果,您必须再次摆脱它。

答案 1 :(得分:0)

尝试:

SELECT
    p.ID,
    p.name,
    p.invoiceTotal,
    maxm.ts
FROM
    project p
    INNER JOIN (
        SELECT m.projectID, max(m.timestamp) ts
        FROM manning m
        WHERE p.ID = m.ProjectID AND m.timestamp BETWEEN 1301118287 AND 1547038287
        GROUP BY m.projectID
    ) maxm ON maxm.projectID = p.id
ORDER BY m.timestamp ASC

答案 2 :(得分:0)

如果您使用的是MySQL 8+或更高版本,那么解决此问题的一种好方法是使用ROW_NUMBER()

WITH cte AS (
    SELECT p.ID, p.Name, p.invoiceTotal, m.timestamp,
        ROW_NUMBER() OVER (PARTITION BY m.ProjectID ORDER BY m.timestamp DESC) rn
    FROM Projects p
    INNER JOIN Manning m
        ON p.ID = m.ProjectID
    WHERE m.timestamp BETWEEN 1301118287 and 1547038287
)

SELECT ID, Name, invoiceTotal, timestamp
FROM cte
WHERE rn = 1;

enter image description here

Demo

如果您使用的MySQL版本早于8,并且希望减少许多查询类型所需编写的代码量,请考虑升级。查看其他答案,了解如何在早期版本的MySQL上解决您的问题。