获取表中每个值的最小时间间隔的行

时间:2014-05-17 13:44:04

标签: sql postgresql aggregate-functions greatest-n-per-group

这是我的表:

Start Time            Stop time                 extension
----------------------------------------------------------
2014-03-03 10:00:00   2014-03-03 11:00:00         100
2014-03-03 10:00:00   2014-03-03 12:00:00         100
2014-03-05 10:00:00   2014-03-05 11:00:00         200
2014-03-03 10:00:00   2014-03-03 13:00:00         100
2014-03-05 10:00:00   2014-03-05 12:00:00         200
2014-03-05 10:00:00   2014-03-05 13:00:00         200

我想获得每个分机的最小时间间隔:

Start Time            Stop time                  Extension
-------------------------------------------------------------
2014-03-03 10:00:00   2014-03-03 11:00:00         100
2014-03-05 10:00:00   2014-03-05 11:00:00         200

如何编写sql?

4 个答案:

答案 0 :(得分:1)

不确定你究竟是什么,但“最小间隔”将是

select min(stop_time - start_time) 
from the_table

如果您还需要两列:

select start_time, stop_time, duration
from (
   select start_time, 
          stop_time,
          stop_time - start_time as duration,
          min(stop_time - start_time) as min_duration
   from the_table
) t
where duration = min_duration;

如果多行具有相同的持续时间,则上述将产生多行。如果您不想要,可以使用:

select start_time, stop_time, duration
from (
   select start_time, 
          stop_time,
          stop_time - start_time as duration,
          row_numer() over (order by stop_time - start_time) as rn
   from the_table
) t
where rn = 1;

答案 1 :(得分:1)

CREATE TABLE fluff
        ( id SERIAL NOT NULL PRIMARY KEY
        , starttime TIMESTAMP NOT NULL
        , stoptime TIMESTAMP NOT NULL
        );

INSERT INTO fluff(starttime,stoptime) VALUES
  ('2014-03-03 10:00:00' , '2014-03-03 11:00:00' )
, ('2014-03-03 10:00:00' , '2014-03-03 12:00:00' )
, ('2014-03-03 10:00:00' , '2014-03-03 13:00:00' )
        ;

SELECT * FROM fluff fl
WHERE NOT EXISTS (
        SELECT *
        FROM fluff nx
        WHERE AGE(nx.stoptime,nx.starttime) < AGE(fl.stoptime,fl.starttime)
        );

好的,更新后:

CREATE TABLE fluff2
        ( id SERIAL NOT NULL PRIMARY KEY
        , starttime TIMESTAMP NOT NULL
        , stoptime TIMESTAMP NOT NULL
        , bagger INTEGER NOT NULL
        );
;

INSERT INTO fluff2(starttime,stoptime, bagger) VALUES
  ( '2014-03-03 10:00:00', '2014-03-03 11:00:00',100)
, ( '2014-03-03 10:00:00', '2014-03-03 12:00:00',100)
, ( '2014-03-05 10:00:00', '2014-03-05 11:00:00',200)
, ( '2014-03-03 10:00:00', '2014-03-03 13:00:00',100)
, ( '2014-03-05 10:00:00', '2014-03-05 12:00:00',200)
, ( '2014-03-05 10:00:00', '2014-03-05 13:00:00',200)
        ;

SELECT * FROM fluff2 fl
WHERE NOT EXISTS (
        SELECT *
        FROM fluff2 nx
        WHERE nx.bagger = fl.bagger
        AND AGE(nx.stoptime,nx.starttime) < AGE(fl.stoptime,fl.starttime)
        );

答案 2 :(得分:0)

我会使用order bylimit

select t.*
from table t
order by stop_time - start_time asc
limit 1;

这为您提供表中所有列的最短持续时间。

答案 3 :(得分:0)

要获取每个extension的最短时间间隔的行(包括所有原始列)(根据您的更新的问题),Postgres特定DISTINCT ON应该是最多的方便:

SELECT DISTINCT ON (extension)
       start_time, stop_time, extension
FROM   tbl
ORDER  BY extension, (stop_time - start_time);

此相关答案的详情:
Select first row in each GROUP BY group?