Запрос базы данных SQL AS400

Столбец времени имеет строковый тип, содержащий время в формате ЧЧММСС. Пример данных:

95030    
122030
132030 

Как видите, ведущих нулей нет.

Я пытаюсь извлечь вышеуказанные значения и преобразовать их во что-то вроде ниже

95030 -> 9:50:30
122030 -> 12:20:30

SQL-запрос:

select cast(Left(TIMECOLUMN, 1,1)||':'||substring(TIMECOLUMN,2,2)||':'||substring(TIMECOLUMN, 4,2) as string) 
from DBNAME.TABLENAME LIMIT 5;

Запрос выше может выполняться только ниже,

95030 -> 9:50:30

Как бы я выступил:

122030 -> 12:20:30

В том же запросе без необходимости выполнять другой запрос?

Спасибо всем заранее!


person Pavan_Obj    schedule 19.03.2019    source источник
comment
Есть ли способ использовать функцию LEN(), определить ее длину и выполнить действие?   -  person Pavan_Obj    schedule 19.03.2019
comment
Вам не все равно, есть ли ведущий «0»?   -  person Strom    schedule 19.03.2019
comment
Нет Strom, у меня может быть 95030 -> 09:50:30, у меня это работает.   -  person Pavan_Obj    schedule 19.03.2019
comment
Как насчет 09:05:03? Он хранится как 953 или 90503?   -  person Satya    schedule 19.03.2019
comment
Отсутствует только начальный символ 0, в остальных случаях присутствует ноль, например: 90504.   -  person Pavan_Obj    schedule 19.03.2019
comment
@Satya, я беру свой предыдущий комментарий обратно, я обнаружил, что в некоторых датах всего 3 символа, например 953.   -  person Pavan_Obj    schedule 19.03.2019
comment
Если любая из трех частей (часы, минуты, секунды) может быть однозначным числом, не существует надежного способа декодирования строки для получения времени. 9123 может быть либо 09:12:03, либо 09:01:23. 11111 может быть либо 01:11:11, либо 11:01:11. Вам следует уточнить у разработчиков программы, которые вставляют/обновляют записи.   -  person Satya    schedule 19.03.2019
comment
Основываясь на других комментариях, похоже, что используется формула (часы * 10000) + (минуты * 100) + секунды. Если это формула, то второе решение, данное @Dinu (с использованием мода), является лучшим вариантом.   -  person Satya    schedule 20.03.2019


Ответы (3)


В DB2 вы можете использовать TO_DATE() (это удобный псевдоним для TIMESTAMP_FORMAT()< /a>), чтобы преобразовать строку в дату, и TO_CHAR() (он же VARCHAR_FORMAT()), чтобы отформатировать его:

SELECT TO_CHAR(TO_DATE(timecolumn, 'HH24MISS'), 'HH24:MI:SS') FROM DBNAME.TABLENAME LIMIT 5

В документации указано, что поддерживаются отсутствующие ведущие нули:

Подстрока строкового выражения, представляющая компонент временной метки (например, год, месяц, день, час, минуты, секунды), может содержать меньше максимального количества цифр для этого компонента временной метки, указанного соответствующим элементом формата. Любые пропущенные цифры по умолчанию равны нулю. Например, со строкой формата 'YYYY-MM-DD HH24:MI:SS' входное значение '999-3-9 5:7:2' даст тот же результат, что и '0999-03-09 05:07:02'.


Как прокомментировали @Dinu и @jmarkmurphy, это может потерпеть неудачу из-за того, что части времени не разделены. В этом случае альтернативный подход состоит в том, чтобы вручную добавить отсутствующие конечные 0(s) перед преобразованием.

SELECT TO_CHAR(
    TO_DATE(
        RIGHT('000000' || timecolumn, 6),
        'HH24MISS'
    ),
    'HH24:MI:SS') 
FROM DBNAME.TABLENAME LIMIT 5
person GMB    schedule 19.03.2019
comment
Таким образом, приведенное выше может обрабатывать оба сценария? 122030 -> 12:20:30 и 95030 -> 09:50:30 преобразовать их в строку? - person Pavan_Obj; 19.03.2019
comment
@Pavan_Obj: согласно документации: да. Мне было бы интересно узнать, работает ли это для вас (у меня нет доступа к базе данных db2, чтобы проверить). - person GMB; 19.03.2019
comment
Проблема в том, что исходный формат не имеет разделителей, таких как :, возможно, синтаксический анализатор не знает, в каком компоненте отсутствуют цифры. Так что, по крайней мере, он должен быть дополнен 0 слева, прежде чем вводить это. - person Dinu; 19.03.2019
comment
Я согласен с Дину, используйте right('0' || TIMECOLUMN, 6) вместо timecolumn, чтобы быть в безопасности. Мой 400 занимает 45 минут до IPL, поэтому я не могу быстро протестировать. - person Strom; 19.03.2019
comment
@Dinu: возможно, вы правы - я тестировал на Oracle, и ошибка возникает, когда отсутствует начальный 0 (в то время как, когда в строке для анализа существуют разделители, это работает). Я обновил свой ответ решением для этого. - person GMB; 19.03.2019
comment
Я постараюсь вернуться сюда, всем спасибо. Искренне ценю вас всех. - person Pavan_Obj; 19.03.2019
comment
Вместо right('0' || timecolumn, 6) я бы использовал right('000000' || timecolumn, 6) для правильной обработки времени около полуночи. Я подозреваю, что упомянутое выше «952» будет не 9:5:2, а 00:09:52. - person jmarkmurphy; 19.03.2019
comment
Это работает с добавлением кода @jmarkmurphy. Однако ссылки предназначены для z/OS, а не для IBM i, как указано в тегах. - person WarrenT; 20.03.2019
comment
Вот соответствующие ссылки для IBM i: TIMESTAMP_FORMAT и VARCHAR_FORMAT. TO_DATE и TO_CHAR являются альтернативными вариантами синтаксиса соответственно. - person jmarkmurphy; 20.03.2019

TO_DATE() недоступен в Db2 для IBM i... Очевидно, он доступен, но задокументирован только в справочнике по SQL как альтернатива синтаксису в функции TIMESTAMP_FORMAT()

TIMESTAMP_FORMAT() (при условии, что вы используете поддерживаемую в настоящее время версию)

Однако для 95030 требуется начальный ноль...

Следующее будет работать

select char(time(timestamp_format(right('0' concat timecolumn ,6),'HH24MISS')))
from DBNAME.TABLENAME
person Charles    schedule 19.03.2019
comment
Хотя это и не задокументировано, TO_DATE кажется синонимом TIMESTAMP_FORMAT на моей машине 7.2. - person jmarkmurphy; 19.03.2019
comment
Точно так же TO_CHAR является синтаксической альтернативой VARCHAR_FORMAT. Мне больше нравятся варианты TO_DATE и TO_CHAR, они лаконичнее. - person jmarkmurphy; 19.03.2019

  • Используйте Right вместо Left. Правостороннее положение фиксируется.

or

  • Используйте SUBSTR с отрицательным индексом. Отрицательный индекс означает справа. т.е. SUBSTR(X,-2,2) — секунды, SUBSTR(X,-4) — часы.

or

  • Рассматривайте его как целое число и используйте, например, MOD (X, 100) для секунд, MOD (FLOOR (X / 100), 100) для минут и т. д.

or

  • если @Strom прав, а SUBSTR не допускает отрицательного индекса - просто добавьте LEN(): SUBSTR(X,LENGTH(X)-2,2) => секунды
person Dinu    schedule 19.03.2019
comment
SUBSTR не может иметь отрицательный индекс в DB2. См. ibm.com/support/knowledgecenter /en/SSEPEK_10.0.0/sqlref/src/tpc/ - person Strom; 19.03.2019