Преобразование числа SQL во время для сравнения дат - PullRequest
4 голосов
/ 16 сентября 2010

Я борюсь со сравнением времени SQL по двум полям, которые были заданы как целые числа, а не как отметки времени.

У меня есть некоторые показатели производительности в базе данных, которые разработчик изначально установил как int (8).База данных содержит время начала и окончания транзакции.Например,

Некоторые примеры данных могут быть

id | start_time | end_time
---------------------------
1  |      85958 | 90001 

Если бы я просто вычел два значения, я бы получил 4043 секунды, когда время транзакции составляет всего 3. Однако я пытаюсь преобразоватьзначения в формате времени, который позволяет мне сравнивать даты.

Я не могу выполнить этот расчет в приложении, потому что в базе данных есть 100 строк в день, и я пытаюсь вычислитьсреднее и максимальное время для транзакций.

РЕДАКТИРОВАТЬ:

Чтобы уточнить

Время в секундах 85958 представляют 8:59:58 90001 представляет 9: 00: 01

Что еще хуже, 1 минута после полуночи 0:01:00 будет представлена ​​как 100.

Ответы [ 5 ]

3 голосов
/ 16 сентября 2010

Предполагая, что вы используете DB2 for LUW, вы можете сделать это, используя несколько функций:

  • DIGITS () - дает вам заполненную нулями строку вашего целого числа
  • TRANSLATE () - переформатировать строку символов
  • MIDNIGHT_SECONDS - вернуть количество секунд с полуночи для времени.

Это будет работать в случаях, когда значение 100 = '00: 01: 00 '.

Пример:

select
   id,
   MIDNIGHT_SECONDS(TRANSLATE('EF:GH:IJ',DIGITS(end_time),'ABCDEFGHIJ')) -
      MIDNIGHT_SECONDS(TRANSLATE('EF:GH:IJ',DIGITS(start_time),'ABCDEFGHIJ')) as runtime
from
   your_table;

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

Конечно, настоящая проблема здесь заключается в использовании INT для хранения ВРЕМЕНИ. Было бы лучше просто исправить вашу модель данных, чтобы она использовала TIME (или лучше TIMESTAMP).

3 голосов
/ 16 сентября 2010

Я тестировал это в MySQL, но уверен, что метод можно адаптировать для работы в DB2:

SELECT
    (end_time DIV 10000) * 3600 +
    ((end_time DIV 100) % 100) * 60 +
    end_time % 100 -
    (start_time DIV 10000) * 3600 -
    ((start_time DIV 100) % 100) * 60 -
    start_time % 100
FROM table1

Результат:

3

Способ, которым это работает, заключается в использовании целочисленного деления и операции по модулю для извлечения частей HH MM и SS каждой метки времени и преобразования каждой части в секунды. Затем секунды складываются вместе, чтобы сформировать общее количество секунд с полуночи для каждой отметки времени. Разница между этими двумя дает время транзакции.

Обратите внимание, что это не будет работать, если транзакция начинается до полуночи и заканчивается после полуночи. Возможно, вам придется подумать, изменился ли день и исправить это. Если у вас нет дня, хранящегося в вашей базе данных, вы можете найти отрицательные времена перехода и добавить 24 часа, чтобы сделать их положительными, и это должно дать правильный результат (если транзакции не превышают одного дня, но Я думаю, что на практике это маловероятно).

Моя попытка написать это для DB2 (не тестировалась):

SELECT
    (end_time / 10000) * 3600 +
    MOD(end_time / 100, 100) * 60 +
    MOD(end_time, 100) -
    (start_time / 10000) * 3600 -
    MOD(start_time / 100, 100) * 60 -
    MOD(start_time, 100)
FROM table1
2 голосов
/ 16 сентября 2010

Я бы предположил, что на самом деле значения должны быть 08:59:58 и 09:00:01 в часах: минутах: секундах, предполагая, что разница в конце равна 3

но это все догадки, которые вам нужно спросить у других в вашей компании, каковы они - поскольку кто-то другой должен был использовать их, даже если оригинальный кодер оставил

2 голосов
/ 16 сентября 2010

Вы уверены, что вам нужно конвертировать? Возможно, число представляет собой миллисекунды, поэтому разница будет ~ 4 секунды.

0 голосов
/ 17 сентября 2010

Большинство уже описанных ответов являются действительными, но, к сожалению, iSeries, похоже, суетится над различными функциями, и поэтому мне пришлось адаптировать ответы, приведенные для его работы.

Окончательное решение, которое я получил, было

select TIME(SUBSTR(DIGITS(END_TIME),1,2) CONCAT ':' CONCAT SUBSTR(DIGITS(END_TIME),3,2) CONCAT ':' CONCAT SUBSTR(DIGITS(END_TIME),5,2)) - TIME(SUBSTR(DIGITS(START_TIME),1,2) CONCAT ':' CONCAT SUBSTR(DIGITS(START_TIME),3,2) CONCAT ':' CONCAT SUBSTR(DIGITS(START_TIME),5,2)) from table1;

Спасибо за все быстрые и подробные ответы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...