2015-11-11 2 views
1

У меня есть таблица с отметками времени изменения элементов:Как масштабировать временную метку от одного диапазона до другого диапазона?

  • ID: INT
  • элемент: INT - внешний ключ
  • создано: TIMESTAMP

мне нужно для определенного элемента, чтобы сжать созданы временные метки для некоторого диапазона. Т.е. .:

  • Диапазон SRC: 1.10.2015 00:00 - 4.10.2015 23:59
  • Диапазон ДСТ: 1.10.2015 00:00 - 1.10.2015 23:59
  • так, образцы TIMESTAMP будет выглядеть так:
    • 2.10.2015 00:00 -> 1.10.2015 6:00
    • 3.10.2015 00:00 -> 1.10.2015 12:00
    • 4.10.2015 00:00 -> 1.10.2015 18:00
    • 4 .10.2015 12:00 -> 1.10.2015 21:00

мне нужно держать год, месяц, день, час, минута, секунды часть полученной отметки времени. Не должно округлять секунды/минуты до нулей.

Точность шкалы не имеет большого значения, но Порядок изменений по созданной метке времени должен быть таким же, как и до масштабирования. Меня не волнуют другие подробности масштабирования: будет ли это начальное/конечное время, включительно/эксклюзивно, или оно масштабируется до 6: 00/5: 59 часов.

Я могу сделать это с помощью некоторого внешнего приложения, которое преобразует его самостоятельно, а затем обновляет временные метки. Однако теперь мне нужно сделать это только с использованием SQL. Является ли это возможным? Это может быть postgres.

Вы можете предположить, что после масштабирования не будет столкновения.

ответ

0

что-то вроде этого?

select id, item, (' ['||created||', '||created_l- '00:00.000001'::time||') ')::tsrange as some_range from (
select id, item, created , lead(created) over(order by created) created_l from my_table order by created) q1 
0
with r (src, dst) as (values 
    (
     tsrange('2015-10-01', '2015-10-05', '[)'), 
     tsrange('2015-10-01', '2015-10-02', '[)') 
    ), 
    (
     tsrange('2015-10-06', '2015-10-10', '[)'), 
     tsrange('2015-10-02', '2015-10-03', '[)') 
    ) 
), t (id, src) as (values 
    (1,'2015-10-02 00:00'::timestamp), 
    (2,'2015-10-03 00:00'), 
    (3,'2015-10-04 00:00'), 
    (4,'2015-10-04 12:00'), 
    (5,'2015-10-06 11:00'), 
    (6,'2015-10-07 15:00') 
) 
select 
    t.id, t.src, 
    lower(r.dst) + rank() over(
      partition by r.dst order by t.src 
    ) * interval '1 second' as squeezed 
from 
    t 
    inner join 
    r on t.src <@ r.src 
; 
id |   src   |  squeezed  
----+---------------------+--------------------- 
    1 | 2015-10-02 00:00:00 | 2015-10-01 00:00:01 
    2 | 2015-10-03 00:00:00 | 2015-10-01 00:00:02 
    3 | 2015-10-04 00:00:00 | 2015-10-01 00:00:03 
    4 | 2015-10-04 12:00:00 | 2015-10-01 00:00:04 
    5 | 2015-10-06 11:00:00 | 2015-10-02 00:00:01 
    6 | 2015-10-07 15:00:00 | 2015-10-02 00:00:02 
Смежные вопросы