如何查找最接近指定日期的最早数据?

时间:2018-08-19 12:58:28

标签: sql postgresql

某些业务数据有一个create_on列来指示创建日期,我想查找最接近指定日期的最早数据。我该怎么写sql?我正在使用postgres数据库。

drop table if exists t;
create table t (
  id int primary key,
  create_on date not null
  -- ignore other columns
);
insert into t(id, create_on) values
  (1, '2018-01-10'::date), 
  (2, '2018-01-20'::date);
  -- maybe have many other data

| sn | specified-date | expected-result         |
| 1  | 2018-01-09     | (1, '2018-01-10'::date) |
| 2  | 2018-01-10     | (1, '2018-01-10'::date) |
| 3  | 2018-01-11     | (1, '2018-01-10'::date) |
| 4  | 2018-01-19     | (1, '2018-01-10'::date) |
| 5  | 2018-01-20     | (2, '2018-01-20'::date) |
| 6  | 2018-01-21     | (2, '2018-01-20'::date) |

1 个答案:

答案 0 :(得分:0)

这很棘手,因为您似乎想要最新的第一行或日期之前的行。但是,如果不存在这样的行,那么您想要表中的最早日期:

with tt as (
      select t.*
      from t
      where t.created_on <= :specified_date
      order by t.created_on desc
      fetch first 1 row only
     )
select tt.*  -- select most recent row before the date
from tt
union all
select t.*   -- otherwise select most oldest row
from t
where not exists (select 1 from tt)
order by t.created_on
fetch first 1 row only;

编辑:

您还可以通过单个查询来处理此问题:

select t.*
from t
order by (t.created_on <= :specified_date) desc,  -- put older dates first
         (case when t.created_on <= :specified_date then created_on end) desc,
         created_on asc
fetch first 1 row only;

尽管这看起来更简单,但实际上可能会更昂贵,因为查询无法使用(created_on)上的索引。而且,没有where子句会减少排序前的行数。