Создать таблицу с соответствующими (виртуальных) столбцов и индексов:
Настройка
Oracle:
CREATE TABLE table_name (
"from" VARCHAR2(10) UNIQUE,
"to" VARCHAR2(10) UNIQUE,
output CHAR(1) NOT NULL,
prefix VARCHAR2(9) GENERATED ALWAYS AS (
CAST(
REGEXP_SUBSTR("from", '^\D+')
AS VARCHAR2(9)
)
) VIRTUAL,
from_postfix NUMBER(9) GENERATED ALWAYS AS (
TO_NUMBER(REGEXP_SUBSTR("from", '\d+$'))
) VIRTUAL,
to_postfix NUMBER(9) GENERATED ALWAYS AS (
TO_NUMBER(REGEXP_SUBSTR("to", '\d+$'))
) VIRTUAL,
CONSTRAINT table_name__from_to__u PRIMARY KEY (
prefix, from_postfix, to_postfix
),
CONSTRAINT table_name__f_t_prefix__chk CHECK (
REGEXP_SUBSTR("from", '\^\D+') = REGEXP_SUBSTR("to", '\^\D+')
)
);
INSERT INTO table_name ("from", "to", output)
SELECT 'A001', 'A555', 'A' FROM DUAL UNION ALL
SELECT 'A556', 'A999', 'B' FROM DUAL UNION ALL
SELECT 'AA01', 'AA55', 'C' FROM DUAL UNION ALL
SELECT 'AA56', 'AA99', 'D' FROM DUAL UNION ALL
SELECT 'B001', 'B555', 'C' FROM DUAL;
COMMIT;
Запрос:
Тогда ваш запрос может использовать индекс и не нужно делать полное сканирование таблицы:
SELECT output
FROM table_name
WHERE REGEXP_SUBSTR(:input, '^\D+') = prefix
AND TO_NUMBER(REGEXP_SUBSTR(:input, '\d+$'))
BETWEEN from_postfix
AND to_postfix;
Выход:
Если переменная input
связывают это AA22
то результат:
OUTPUT
------
C
Explain Plan:
PLAN_TABLE_OUTPUT
-------------------------------------------
Plan hash value: 2408507965
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 35 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TABLE_NAME | 1 | 35 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TABLE_NAME__FROM_TO__U | 1 | | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("PREFIX"= REGEXP_SUBSTR (:INPUT,'^\D+') AND "TO_POSTFIX">=TO_NUMBER(
REGEXP_SUBSTR (:INPUT,'\d+$')) AND "FROM_POSTFIX"<=TO_NUMBER(REGEXP_SUBSTR (:INPUT,'\d+$')))
filter("TO_POSTFIX">=TO_NUMBER(REGEXP_SUBSTR (:INPUT,'\d+$')))
Что вы входное значение? Действительно непонятно, как АА становится «С» ... – Ben
Каков диапазон букв? –
Предположим, что я получил Input как A123, поэтому это значение больше A001 и меньше A555, поэтому запрос должен возвращать «A» из столбца вывода. Если I Received Input as AA12, то это значение больше AA01 и меньше AA99, поэтому запрос должен возвращать «A». Запрос сначала должен проверить исходные алфавиты, а затем сравнить числа для этой строки. Надеюсь, я здесь ясен. – sach