在给定datetime参数的SQL Query中获取最接近的created_at时间

时间:2017-01-06 14:43:26

标签: mysql sql

我正在尝试做这样的事情SQL query to get most recent row for each instance of a given key

但是我没有使用max(created_at),而是提供了一个我将在查询中使用的某个created_at值。

这是我的示例数据。我有40个唯一的node_ids

+---------+---------------------+
| node_id | created_at          |
+---------+---------------------+
|      26 | 2017-01-05 17:35:14 |
|       5 | 2017-01-05 14:58:16 |
|      22 | 2017-01-05 14:58:16 |
|      20 | 2017-01-05 14:58:16 |
|      15 | 2017-01-05 14:58:16 |
|      12 | 2017-01-05 14:58:16 |
|       8 | 2017-01-05 14:58:16 |
|      11 | 2017-01-05 14:58:16 |
|      33 | 2017-01-05 14:58:16 |
|      23 | 2017-01-05 14:58:16 |
|       4 | 2017-01-05 14:58:16 |
|      39 | 2017-01-05 14:57:30 |
|      30 | 2017-01-05 14:57:30 |
|      26 | 2017-01-05 14:57:30 |
|      17 | 2017-01-05 14:57:30 |
|      16 | 2017-01-05 14:57:30 |
|      37 | 2017-01-05 14:42:42 |
|      35 | 2017-01-05 14:42:42 |
|      13 | 2017-01-05 14:42:42 |
|      21 | 2017-01-05 14:42:20 |
|      25 | 2017-01-05 14:42:20 |
|      14 | 2017-01-05 14:42:20 |
|       9 | 2017-01-05 14:42:20 |
|       2 | 2017-01-05 14:42:20 |
|      38 | 2017-01-05 14:41:36 |
|      29 | 2017-01-05 14:41:36 |
|      28 | 2017-01-05 14:41:36 |
|      24 | 2017-01-05 14:41:36 |
|      18 | 2017-01-05 14:41:36 |
|       7 | 2017-01-05 14:41:36 |
|       1 | 2017-01-05 14:41:36 |
|      32 | 2017-01-05 14:41:36 |
|      10 | 2017-01-05 14:41:36 |
|      36 | 2017-01-05 14:41:36 |
|      19 | 2017-01-05 14:40:47 |
|      27 | 2017-01-05 14:40:47 |
|      31 | 2017-01-05 14:40:47 |
|      34 | 2017-01-05 14:40:47 |
|      35 | 2017-01-05 14:40:47 |
|      37 | 2017-01-05 14:40:47 |
|      40 | 2017-01-05 14:40:47 |
|       3 | 2017-01-05 14:40:47 |
|       6 | 2017-01-05 14:40:47 |
|      13 | 2017-01-05 14:40:21 |
|       1 | 2017-01-05 14:40:09 |
|       2 | 2017-01-05 14:40:09 |
|       3 | 2017-01-05 14:40:09 |
|       4 | 2017-01-05 14:40:09 |
|       5 | 2017-01-05 14:40:09 |
|       6 | 2017-01-05 14:40:09 |
|       7 | 2017-01-05 14:40:09 |
|      40 | 2017-01-05 14:40:09 |
|      33 | 2017-01-05 14:40:09 |
|      39 | 2017-01-05 14:40:09 |
|      38 | 2017-01-05 14:40:09 |
|      37 | 2017-01-05 14:40:09 |
|      36 | 2017-01-05 14:40:09 |
|      35 | 2017-01-05 14:40:09 |
|      34 | 2017-01-05 14:40:09 |
|      32 | 2017-01-05 14:40:09 |
|      31 | 2017-01-05 14:40:09 |
|      30 | 2017-01-05 14:40:09 |
|      29 | 2017-01-05 14:40:09 |
|      28 | 2017-01-05 14:40:09 |
|      27 | 2017-01-05 14:40:09 |
|      26 | 2017-01-05 14:40:09 |
|      25 | 2017-01-05 14:40:09 |
|      24 | 2017-01-05 14:40:09 |
|      23 | 2017-01-05 14:40:09 |
|      22 | 2017-01-05 14:40:09 |
|      21 | 2017-01-05 14:40:09 |
|      20 | 2017-01-05 14:40:09 |
|      19 | 2017-01-05 14:40:09 |
|      11 | 2017-01-05 14:40:09 |
|      18 | 2017-01-05 14:40:09 |
|      17 | 2017-01-05 14:40:09 |
|      16 | 2017-01-05 14:40:09 |
|      15 | 2017-01-05 14:40:09 |
|      14 | 2017-01-05 14:40:09 |
|      13 | 2017-01-05 14:40:09 |
|      12 | 2017-01-05 14:40:09 |
|      10 | 2017-01-05 14:40:09 |
|       9 | 2017-01-05 14:40:09 |
|       8 | 2017-01-05 14:40:09 |
+---------+---------------------+

我在这里使用的查询是:

从nodes_position选择node_id,created_at,其中created_at< ='2017-01-05 17:35:14'按create_at desc排序;

我想要做的是只将最接近的created_at的行添加到我提供的行中,并使用uniquer_id。

我应该拥有的结果是这样的(只有40行,因为只有40个唯一的node_id)

+---------+---------------------+
| node_id | created_at          |
+---------+---------------------+
|      26 | 2017-01-05 17:35:14 |
|       5 | 2017-01-05 14:58:16 |
|      22 | 2017-01-05 14:58:16 |
|      20 | 2017-01-05 14:58:16 |
|      15 | 2017-01-05 14:58:16 |
|      12 | 2017-01-05 14:58:16 |
|       8 | 2017-01-05 14:58:16 |
|      11 | 2017-01-05 14:58:16 |
|      33 | 2017-01-05 14:58:16 |
|      23 | 2017-01-05 14:58:16 |
|       4 | 2017-01-05 14:58:16 |
|      39 | 2017-01-05 14:57:30 |
|      30 | 2017-01-05 14:57:30 |
|      17 | 2017-01-05 14:57:30 |
|      16 | 2017-01-05 14:57:30 |
|      37 | 2017-01-05 14:42:42 |
|      35 | 2017-01-05 14:42:42 |
|      13 | 2017-01-05 14:42:42 |
|      21 | 2017-01-05 14:42:20 |
|      25 | 2017-01-05 14:42:20 |
|      14 | 2017-01-05 14:42:20 |
|       9 | 2017-01-05 14:42:20 |
|       2 | 2017-01-05 14:42:20 |
|      38 | 2017-01-05 14:41:36 |
|      29 | 2017-01-05 14:41:36 |
|      28 | 2017-01-05 14:41:36 |
|      24 | 2017-01-05 14:41:36 |
|      18 | 2017-01-05 14:41:36 |
|       7 | 2017-01-05 14:41:36 |
|       1 | 2017-01-05 14:41:36 |
|      32 | 2017-01-05 14:41:36 |
|      10 | 2017-01-05 14:41:36 |
|      36 | 2017-01-05 14:41:36 |
|      19 | 2017-01-05 14:40:47 |
|      27 | 2017-01-05 14:40:47 |
|      31 | 2017-01-05 14:40:47 |
|      34 | 2017-01-05 14:40:47 |
|      35 | 2017-01-05 14:40:47 |
|      37 | 2017-01-05 14:40:47 |
|      40 | 2017-01-05 14:40:47 |
|       3 | 2017-01-05 14:40:47 |
|       6 | 2017-01-05 14:40:47 |
|      13 | 2017-01-05 14:40:21 |
+---------+---------------------+

如何做到这一点?感谢。

2 个答案:

答案 0 :(得分:0)

从根本上说,你正在寻找最小的时差......

select *
from nodes_position  a1
where abs(timediff(@my_time, a1.created_at)) 
      = (select min(abs(timediff(@my_time,np.created_at))) 
         from nodes_position np)

答案 1 :(得分:0)

你的意思是?

SELECT node_id, MAX(created_at) FROM nodes_position WHERE created_at <= '2017-01-05 17:35:14' GROUP BY node_id ORDER BY node_id;

您还可以ORDER BY 2按created_at排序。

此处GROUP BY node_id将所有具有相同node_id的行组合在一起

node_id | created_at
   5    | 2000-01-01
   5    | 2222-01-01
   7    | 3333-01-01

进入

node_id | created_at
   5    | { 2000-01-01, 2222-01-01 }  <-- MAX({ 2000-01-01, 2222-01-01 }) = 2222-01-01
   7    | { 3333-01-01 }

并且WHERE只允许行参与GROUPing等于或低于created_at的行。