SQL查找的行的值最接近指定值集中的每个值

时间:2016-01-27 12:12:51

标签: php sql postgresql symfony doctrine-orm

我在数据库中每6小时收集一次统计信息,每个统计信息都使用时间戳保存。然后我的代码中有时间戳数组。我需要从数据库中为我的时间戳数组中的每个值选择一个值,该行的时间戳最接近或等于数组中的值。

说明: 带数据的表

Id   Timestamp   Value
1    1400000027  10
2    1400000035  15
3    1400000043  20
4    1400000044  21
5    1400000048  30
6    1400000060  35

该数组包含以下时间戳:

[1400000020, 1400000024, 1400000035, 1400000050]

我需要根据输入数组从数据库获取的行是:

Id   Timestamp   Value
1    1400000027  10
1    1400000027  10
2    1400000035  15
6    1400000060  35

有一种简单的方法可以在一个查询中执行此操作吗?最好的解决方案是学说,因为我使用的是Symfony 2和Doctrine。

2 个答案:

答案 0 :(得分:3)

说实话,对每个值执行单独的查询可能最简单:

select t.*
from table t
where t.TimeStamp >= $timestamp
order by TimeStamp
limit 1;

使用TimeStamp上的索引,此查询应该非常快。

您可以在单个查询中执行此操作。我倾向于将值存储在表中(如果需要,可以展开数组值)。在Postgres 9.3及更高版本中,您可以将其称为横向连接:

with timestamps as (
      select 1400000020 as ts union all
      select 1400000024 union all
      select 1400000035 union all
      select 1400000050
     )
select t.*
from timestamps cross join lateral
     (select
      from table t
      where t.timestamp >= timestamps.ts
      order by t.timestamp
      limit 1
     ) t;

答案 1 :(得分:1)

这通常在PostgreSQL中使用DISTINCT ON完成(如果您可以使用非标准SQL)

SELECT    DISTINCT ON (ts_min) t.*
FROM      unnest(ARRAY[1400000020, 1400000024, 1400000035, 1400000050]) ts_min
LEFT JOIN table_name t ON t.timestamp >= ts_min
ORDER BY  ts_min, t.timestamp

如果无法绑定数组,可以使用values 构造

FROM      (VALUES (1400000020), (1400000024), (1400000035), (1400000050)) v(ts_min)

相关解决方案: