SQL-запрос для перевода списка чисел, сопоставляемых с несколькими диапазонами, в список значений

Мне нужно преобразовать список чисел, входящих в определенные диапазоны, в список значений, упорядоченный по столбцу приоритета. Таблица имеет следующие значения:

| YEAR | R_MIN | R_MAX | VAL | PRIO | ------------------------------------ 2010 18000 90100 52 6 2010 240000 240099 82 3 2010 250000 259999 50 5 2010 260000 260010 92 1 2010 330000 330010 73 4 2010 330011 370020 50 5 2010 380000 380050 84 2 

Диапазоны будут отличаться для разных лет. Диапазоны в течение одного года никогда не будут перекрываться.

Вход будет годом и списком чисел, которые могут находиться в пределах одного диапазона. Список входных номеров будет небольшим, от 1 до 10 номеров. Пример номеров ввода:

 (20000, 240004, 375000, 255000) 

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

 82 50 52 

Единственное, что меня интересует, это 82 , поэтому UNIQUE и MAX_RESULTS = 1. Его можно легко сделать с помощью одного запроса на номер, а затем отсортировать его в Java-коде, но я бы предпочел сделать это в одном SQL-запросе.

Какой SQL-запрос, который будет запущен в базе данных Oracle, даст мне желаемый результат?

(Обратите внимание, что речь идет не о разбиении входной строки , а в сопоставлении каждого значения в списке значений с диапазонами, определенными в разных столбцах.)

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

    Существует ряд решений для токенизаторов PL / SQL, сбивающих Das Interwabs. Я использую вариант реализации Anup Pani , который использует Regex (отсюда только Oracle 10g или выше). Мой вариант возвращает массив чисел, который я объявил как тип SQL:

     SQL> create or replace type numbers as table of number 2 / Type created. SQL> 

    Это означает, что я могу использовать его как вход для функции TABLE () в инструкции SELECT:

     SQL> select * from table (str_to_number_tokens('20000, 240004, 375000, 255000')) 2 / COLUMN_VALUE ------------ 20000 240004 375000 255000 SQL> 

    Это означает, что я могу превратить вашу строку чисел в таблицу, к которой я могу присоединиться в запросе, например:

     SQL> select val 2 from t23 3 , ( select column_value as i_no 4 from table (str_to_number_tokens('20000, 240004, 375000, 255000')) ) sq 5 where t23.year = 2010 6 and sq.i_no between t23.r_min and t23.r_max 7 order by t23.priority 8 / VAL ---------- 82 50 52 SQL> 

    Я думаю, что ваша первая задача состояла бы в преобразовании списка чисел в набор результатов (т. Е. В таблицу памяти), к которому вы можете присоединиться. Я не знаю Oracle, поэтому может быть простой способ сделать это, но если нет, вам нужно будет написать какую-то пользовательскую функцию, которая сделает это. Это не должно быть слишком сложно, и производительность не является проблемой, так как список невелик. Затем вы можете присоединиться к этой таблице. Что-то вроде этого:

     SELECT yt.val FROM your_table yt JOIN your_parse_numbers_function(@inputlist) il ON il.value >= yt.R_MIN AND il.value <= yt.R_MAX WHERE yt.YEAR = @year 

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