получение крайних правых символов в поле в SQL без RIGHT()

#sql #ibm-midrange

#sql #ibm-средний уровень

Вопрос:

я работаю над старым AS400, который не поддерживает функцию SQL RIGHT (), и мне нужно выбирать строки на основе X крайних правых символов числа, длина которого может составлять 7 или 8 символов, используя SQL.

Как я могу получить то, что я хочу, если я не могу использовать RIGHT и не знаю точной длины числа?.

вот некоторый контекст на случай, если это окажется полезным:

Число является датой, но было сохранено как число, поэтому база данных удаляет первый ноль, в результате чего даты, начинающиеся с нуля, такие как 01032016 [читается как 01-03-2016], обрезаются до 1032016).

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

Изменение формата дат в базе данных на что-то более разумное вызвало бы критические изменения в программном обеспечении, которое я не поддерживаю, и это критически важно.

Комментарии:

1. поддерживает ли он SUBSTRING()?

Ответ №1:

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

Предполагая, что данные были сохранены в виде упакованной или разделенной на зоны десятичной дроби, а не целого числа (очень вероятно), затем используйте DIGITS() для преобразования числа в фиксированный символ, включая начальные нули, а затем вы можете использовать SUBSTR()

Комментарии:

1. В итоге это был самый простой ответ на мою проблему, спасибо!.

Ответ №2:

 SUBSTRING(mystr,character_length(mystr)-x 1,x)
  

или

 SUBSTRING(mystr,character_length(mystr)-x 1)
  

Комментарии:

1. Это `character_length’ в DB2.

2. publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/…

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

4. Спасибо @TracyProbst, в целом вы правы. В данном конкретном случае мы знаем, что данные представляют собой «число, длина которого может составлять 7 или 8 символов»

5. К сожалению, character_length() также не поддерживается :/

Ответ №3:

Поддерживает ли он modulo?

Входные данные: 1032016

 // Outputs: 2016
YOURDATEASINT % 10000 AS Year

MOD(YOURDATEASINT, 10000) AS Year

// Outputs: 32016
YOURDATEASINT % 1000000 AS MonthYear

MOD(YOURDATEASINT, 1000000) AS MonthYear

// Outputs: 1032016
YOURDATEASINT % 100000000 AS DayMonthYear

MOD(YOURDATEASINT, 100000000) AS DayMonthYear
  

Комментарии:

1. Привет, frumroll, к сожалению, мне нужно получить любую часть даты, это может быть год, год и месяц или год, месяц и день.

2. Вы все еще можете использовать MOD, просто измените 10000 по мере необходимости. Это эффективно работает так же, как и RIGHT, но только для чисел.

3. В конце концов, я решил использовать это, это обеспечило лучшую замену в моем случае использования.

4. есть ли вероятность, что этот метод очень медленный? я просматриваю 1,5 миллиона записей, и базе данных требуется 32 секунды, чтобы вернуть ответ.

Ответ №4:

Что меня поражает, так это то, что даты, сохраненные в виде чисел, даже не представлены в форме ГГГГММДД. Поэтому фильтрация по диапазону этих значений, охватывающему более одного года, особенно раздражает.

Единственное, что вы можете сделать, если у вас есть полномочия на создание таблиц и индексов, — это создать таблицу дат, в которой просто перечислены все возможные даты в некотором очень большом диапазоне. (150 000 записей охватывают более 400 лет, и по сегодняшним стандартам это небольшая таблица.) Эта таблица будет включать в себя несколько форматов, включая, по крайней мере, один, который является подлинным столбцом типа ДАТЫ, и тот, который вы пытаетесь обработать (в данном случае, 8-значное число, представляющее либо MMDDYYYY, либо DDMMYYYYY). Тогда вы можете использовать объединение, чтобы использовать возможности механизма запросов SQL, вместо того, чтобы выполнять вычисление функции для каждой строки данных (что и должно произойти, если вы преобразуете свои данные с использованием встроенного SQL).

Комментарии:

1. Спасибо за ваш вклад, но, к сожалению, я не думаю, что у меня есть такие полномочия, но я посмотрю, смогу ли я добиться, чтобы правильное форматирование в языках, говорящих на латинице (в данном случае в Аргентине), было ДД-ММ-ГГГГ в отличие от ГГГГ-ММ-ДД. Подробнее об этом можно прочитать здесь en.wikipedia.org/wiki/Date_format_by_country

2. Я знаком со всеми видами форматирования даты, но обычный способ обработки различного форматирования заключается в преобразовании «локального» формата в более удобный для вычислений формат хранения (если возможно, истинная ДАТА, иначе ГГГГММДД) в самый ранний возможный момент ввода и из формата хранения в локальный формат в самый поздний возможный момент вывода. Как MMDDYYYY, так и DDMMYYYYY ужасны для вычислений. На самом деле DDMMYYYY хуже всего, потому что вы даже не можете напрямую указать диапазон, охватывающий более одного месяца.

Ответ №5:

В то время как подстрока (цифры (date_column), x, y) является опцией, другой вариант представляет собой комбинацию функции MOD и разделения. Например, чтобы получить год, используйте это: SELECT MOD(date_column,10000) , чтобы получить день, используйте это: CAST(MOD(date_column,1000000)/10000 AS INT) , а чтобы получить месяц, используйте это: CAST(date_column/1000000 AS INT) .