J'ai besoin de sélectionner une sous-chaîne pour obtenir le numéro consécutif à partir d'un champ de table. Ma table est:

ORDER_NUM       ORDER_DATE   ORDER_TYPE  LOCATION   SALE_TYPE
10501702315618  08/01/17       43223       1050        18    
105017023186230 21/01/17       43221       1050        230

Le champ ORDER_NUM est généré comme suit

[LOCATION] + [YY] + [CONSECUTIVE_NUMBER] + [SALE_TYPE]

La longueur des champs LOCATION et SALE_TYPE peut être différente, donc ma requête est:

SELECT 
SUBSTR(ORDER_NUM,LENGTH (ORDER_TYPE)  + 3,LENGTH (ORDER_NUM)   - LENGTH ( SALE_TYPE ) ),
ORDER_DATE
FROM 
CAT_ORDERS
WHERE 
LOCATION = '1050'
AND SALE_TYPE = '18'

Le résultat est

    SELECT SUBSTR('10501702315618',7,12) from dual
    RESULT: 02315618

Où la position d'index est:

 12345678901234
 10501702315618

Comment puis-je supprimer les caractères SALE_TYPE de la chaîne? Il y a une autre fonction pour cela?

Merci!

1
Matías W. 26 janv. 2017 à 21:35

4 réponses

Meilleure réponse

Votre description fait référence à l'emplacement, il est donc étrange que votre décalage soit basé sur le type de commande. La longueur de la sous-chaîne doit également exclure la longueur de l'emplacement et l'année:

SUBSTR(ORDER_NUM, LENGTH (LOCATION) + 3,
  LENGTH (ORDER_NUM) - LENGTH(LOCATION) - 2 - LENGTH (SALE_TYPE))

Pour le moment, vous obtenez 12 caractères de votre décalage, alors que vous n'en voulez que six et qu'il n'y en a que huit disponibles.

Démo avec vos données:

WITH CAT_ORDERS (ORDER_NUN, ORDER_DATE, ORDER_TYPE, LOCATION, SALE_TYPE) AS (
  SELECT 10501702315618, TO_DATE('08/01/17', 'DD/MM/RR'), 43223, 1050, 18 FROM DUAL
  UNION ALL SELECT 105017023186230, TO_DATE('21/01/17', 'DD/MM/RR'), 43221, 1050, 230 FROM DUAL
)
SELECT SUBSTR(ORDER_NUM, LENGTH (LOCATION) + 3,
  LENGTH (ORDER_NUM) - LENGTH(LOCATION) - 2 - LENGTH (SALE_TYPE))
FROM CAT_ORDERS;

023156
023186

Votre numéro de commande duplique les données d'autres colonnes, ce qui ne semble pas idéal. Il serait plus simple de stocker uniquement la partie "numéro consécutif" à la place et de générer le numéro de commande complet sous forme de colonne virtuelle.

4
mathguy 26 janv. 2017 à 19:49
select  regexp_substr(ORDER_NUM,'^' || LOCATION || '..(.*)' || SALE_TYPE || '$',1,1,'',1)
from    mytable;

Puisque nous savons maintenant que la longueur de consecutive_number est fixe (à savoir, 6):

select  regexp_substr(ORDER_NUM,'^' || LOCATION || '..(.{6})',1,1,'',1)
from    mytable;

Ou

select  regexp_substr(ORDER_NUM,'(.{6})' || SALE_TYPE || '$',1,1,'',1)
from    mytable;
2
David דודו Markovitz 26 janv. 2017 à 19:46

Puisque nous savons maintenant que la longueur de consecutive_number est fixe (à savoir, 6):

select  substr(ORDER_NUM,length(LOCATION)+3,6)
from    mytable;

Ou

select  substr(ORDER_NUM,-length(SALE_TYPE)-6,6)
from    mytable;
1
mathguy 26 janv. 2017 à 19:47

Cela devrait supprimer les caractères sale_type de la fin:

select 
  substr(substr(order_num, 0, length(order_num)-length(sale_type)), length(location) + 3)
from t;
2
Gurwinder Singh 26 janv. 2017 à 18:49