按一列选择最新记录组

时间:2017-09-14 08:10:51

标签: mysql inner-join

我有这个表,我必须从中选择每个位置的最新行

|   location   |    parameter   |   datetime                | value |
---------------------------------------------------------------------
|   Location 1 |    P1          |   2017-09-13 05:00:00     | 0.68  |
|   Location 1 |    P2          |   2017-09-13 05:00:00     | 6     |
|   Location 1 |    P3          |   2017-09-13 06:00:00     | 19    |
|   Location 1 |    P4          |   2017-09-13 06:00:00     | 1     |
|   Location 2 |    P1          |   2017-09-13 05:00:00     | 0.1   |
|   Location 2 |    P2          |   2017-09-13 05:00:00     | 2     |
|   Location 2 |    P3          |   2017-09-13 06:00:00     | 26    |
|   Location 2 |    P5          |   2017-09-13 06:00:00     | 7.9   |
|   Location 2 |    P4          |   2017-09-13 07:00:00     | 0     |
|   Location 3 |    P1          |   2017-09-13 04:00:00     | 0.47  |
|   Location 3 |    P2          |   2017-09-13 05:00:00     | 1     |
|   Location 3 |    P3          |   2017-09-13 04:00:00     | 25    |
|   Location 3 |    P5          |   2017-09-14 05:00:00     | 3.8   |
---------------------------------------------------------------------

enter image description here

我尝试了以下查询,但两者都没有返回每个位置的最新数据。

SELECT * FROM mytable WHERE 
datetime in (SELECT max(datetime) FROM myTable Group by location) 
group by location;

AND

SELECT * FROM myTable AS t1
INNER JOIN
(
   SELECT MAX(datetime) AS maxDate
   FROM myTable
   GROUP BY location
) AS t2  ON t1.datetime = t2.maxDate group by t1.location;

两个查询都返回位置2的错误数据。

完成此操作后,我还想在查询中添加另一个条件,其中最新日期相同,然后按值desc排序,并选择具有最高值的记录。

预期输出

|   location   |    parameter   |   datetime                | value |
---------------------------------------------------------------------
|   Location 1 |    P3          |   2017-09-13 06:00:00     | 19    |
|   Location 2 |    P4          |   2017-09-13 07:00:00     | 0     |
|   Location 3 |    P5          |   2017-09-14 05:00:00     | 3.8   |
---------------------------------------------------------------------

但我正在尝试的查询为位置2返回错误的日期。

感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

您需要先获取每个位置的最新时间,例如:

SELECT location, MAX(`datetime`) 
FROM table 
GROUP BY location;

然后,使用同一个表加入它,例如:

SELECT t1.*
FROM table t1 JOIN (
    SELECT location, MAX(`datetime`) 
    FROM table 
    GROUP BY location
) a
ON t1.location = a.location AND t1.datetime = a.datetime;

您可以通过添加ORDER BY t1.value DESC或任何其他列来订购结果。

答案 1 :(得分:1)

您可以使用变量:

SELECT location, parameter, datetime, value
FROM (
   SELECT location, parameter, datetime, value,
          @seq := IF(@loc = location, @seq + 1,
                     IF(@loc := location, 1, 1)) AS seq
   FROM mytable
   CROSS JOIN (SELECT @seq := 0, @loc = '') AS vars
   ORDER By location, datetime desc, value desc) AS t
WHERE t.seq = 1

内部查询具有ORDER BY子句,该子句首先在其自己的切片中返回所需的每组最新记录。使用@seq函数实现的逻辑,第一个记录的变量IF设置为1。外部查询只是过滤派生表以获取每个location切片的预期记录。

Demo here