IBM i Date Diff с CYYMMDD - нельзя использовать DATE()

(название отредактировано) Добрый день всем!

Использование IBM i версии 7.1 и поиск разницы между двумя датами в запросе. Поскольку ничто никогда не бывает легким, одна дата находится в формате CYYMMDD, а другая (curdate()) — в формате YYYY-MM-DD. Я попытался преобразовать дату в формате CYYMMDD (имя поля APENGD) в виде varchar (10), а затем обернул ее в CAST как дату (поскольку десятичные числа нельзя преобразовать в даты):

Cast(Cast(APENGD + 19000000 As varchar(10)) As date) As math

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

Заранее спасибо!

Мэтт


person user3593083    schedule 06.07.2016    source источник
comment
Как вы планируете рассчитывать разницу в DB2? Я не знаю никаких хороших встроенных функций, и TIMESTAMPDIFF почти бесполезен.(из-за предыдущей математики даты). Кроме того, использование разницы между столбцами часто приводит к игнорированию индексов (поскольку для этого требуется информация об оценке для каждой строки) - что вы планируете делать с этой разницей?   -  person Clockwork-Muse    schedule 12.07.2016


Ответы (3)


приведение varchar к дате работает только тогда, когда строка включает разделители.

В версии 7.1 вы могли бы использовать TIMESTAMP_FORMAT(), но вместо даты вы бы получили метку времени. Но это легко лечится.

Date(Timestamp_format(char(APENGD + 19000000),'YYYYMMDD')) As math

Мое предпочтительное решение при работе с датами числового/символьного значения — создание пользовательской функции для обработки преобразования.

Вы можете написать свой собственный или использовать тот, который я делаю. iDate, написанный Аланом Кампином. Тогда ваш код будет простым:

   idate(APENGD,'*CYMD') as nath

Обратите внимание, что если вы пытаетесь использовать разницу дат в предложении WHERE, например

WHERE CURRENT_DATE - 3 months <= idate(APENGD,'*CYMD') 

Вышеприведенное будет плохо работать, поскольку существующий индекс поверх APENGD нельзя использовать (напрямую). Предполагая недавнюю (6.1+) версию ОС, вы можете создать новый индекс, который включает выражение, которое вы используете для преобразования APENGD в актуальное состояние.

Или вы можете закодировать его, используя функцию Date->Numeric ConvertToIdate, которую услужливо включил Алан. Это позволит использовать существующие индексы.

WHERE ConvertToiDate(CURRENT_DATE - 3 months,'*CYMD') <= APENGD
person Charles    schedule 06.07.2016
comment
Спасибо, Чарльз! решение TIMESTAMP_FORMAT работает отлично. - person user3593083; 07.07.2016
comment
Предложение WHERE может быть улучшено с помощью INDEX вместо выражения, которое преобразует APENGD в форму DATE. Начиная с i 6.1, выражения разрешены для индексов. Поэкспериментируйте, чтобы найти хороший вариант. - person user2338816; 08.07.2016

DDL не предлагался [для определения столбца APENGD]. Неважно, поскольку следующего должно быть достаточно, в основном независимо от определения; либо в виде строки, либо в виде числового значения с нулевой шкалой. Эффект зависит от распознавания SQL 14-символьной [до 26-символьной, начиная с некоторых версий v7] символьной строки как неформатированной [т.е. без каких-либо разделителей, поэтому только цифры] представление TIMESTAMP:

date(timestamp((APENGD + 19000000) concat '000000'))

IBM i 7.3->База данных->Справочник->Справочник по SQL-> Элементы языка->Типы данных->Значения даты и времени->Строковые представления значений даты и времени->Строки меток времени

Строковое представление временной метки — это символ или графическая строка Unicode, которая начинается с цифры и имеет длину не менее 14 символов. …

person CRPence    schedule 11.07.2016

Если вы хотите рассчитать разницу между двумя датами, вы можете использовать:

`TIMESTAMPDIFF(32, cast(MYTIMESTAMP1 - MYTIMESTAMP2 as char(22)))`

Первый аргумент функции указывает тип результата.

1 : миллисекунда 16 : дни 2 : секунды 32 : неделя 4 : минуты 64 : месяц 8 : час 128 : триместр 256 : год

person Esperento57    schedule 09.07.2016
comment
Пожалуйста, никогда не используйте TIMESTAMPDIFF (или действительно вычитание метки времени): он вычисляет результаты на основе оценок, которые будут отбрасывать результаты, когда вы меньше всего этого ожидаете, как Я объясняю здесь. - person Clockwork-Muse; 12.07.2016
comment
я этого не знал, спасибо ;) - person Esperento57; 13.07.2016