Erstellen Sie Ihre Tabelle mit den entsprechenden (virtuellen) Spalten und Indizes vergleichen:
Oracle-Setup:
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;
Abfrage:
dann Ihre Abfrage den Index benötigen verwenden kann und nicht einen vollständigen Tabellenscan zu tun:
SELECT output
FROM table_name
WHERE REGEXP_SUBSTR(:input, '^\D+') = prefix
AND TO_NUMBER(REGEXP_SUBSTR(:input, '\d+$'))
BETWEEN from_postfix
AND to_postfix;
Ausgang:
Wenn der input
Bind Variable AA22
ist dann ist das Ergebnis:
OUTPUT
------
C
Erklären-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+$')))
Was ist Ihr Eingabewert? Es ist wirklich nicht klar, wie AA "C" wird ... – Ben
Was ist der Bereich der Buchstaben? –
Angenommen, ich habe Input als A123 erhalten, also ist dieser Wert größer als A001 und kleiner als A555, daher sollte die Abfrage "A" aus der Ausgabespalte zurückgeben. Wenn ich Input als AA12 erhalten habe, dann ist dieser Wert größer als AA01 und kleiner als AA99, daher sollte die Abfrage "A" zurückgeben. Abfrage sollte zuerst die anfänglichen Alphabete überprüfen und dann die Zahlen für diese Zeile vergleichen. Ich hoffe, dass ich hier klar bin. – sach