2009-02-27 7 views
2

Supposons qu'il existe une table "A" avec 2 colonnes - ID (INT), DATA (VARCHAR (100)). exécution « SELECT des données d'un » résultats dans un tableau ressemble à:Comment extraire des données numériques du résultat SQL

DATA 
--------------------- 
Nowshak 7,485 m 
Maja e Korabit (Golem Korab) 2,764 m 
Tahat 3,003 m 
Morro de Moco 2,620 m 
Cerro Aconcagua 6,960 m (located in the northwestern corner of the province of Mendoza) 
Mount Kosciuszko 2,229 m 
Grossglockner 3,798 m 
// the DATA continues... 
--------------------- 

Comment puis-je extraire uniquement les données numériques en utilisant une sorte de fonction de traitement de chaîne dans la requête SQL SELECT afin que le résultat d'un SELECT modifié ressemblerait à ceci:

DATA (in INTEGER - not varchar) 
--------------------- 
7485 
2764 
3003 
2620 
6960 
2229 
3798 
// the DATA in INTEGER continues... 
--------------------- 

Par ailleurs, il serait préférable que cela puisse être fait dans une seule instruction SQL. (J'utilise IBM DB2 version 9.5)

de Merci :)

+0

Quelle plate-forme utilisez-vous? – Quassnoi

+0

IBM DB2 version 9.5 (La nouvelle version prenant en charge le stockage XML en mode natif.) – natch3z

Répondre

2

En Oracle:

SELECT TO_NUMBER(REGEXP_REPLACE(data, '[^0-9]', '')) 
FROM a 

En PostgreSQL:

SELECT CAST(REGEXP_REPLACE(data, '[^0-9]', '', 'g') AS INTEGER) 
FROM a 

En MS SQL Server et DB2, vous devrez créer UDF pour les expressions régulières et requête comme ceci.

Voir les liens pour plus de détails.

+0

Je suis désolé. J'ai oublié de mentionner que j'utilise DB2 version 9.5. – natch3z

+0

n'a jamais su que vous pouvez utiliser regex en sql +1 –

+0

pouvez-vous poster un pour MSSQL Server? –

2

Faire une recherche rapide en ligne pour DB2 la meilleure fonction intégrée que je peux trouver est Translate Il vous permet de spécifier une liste de caractères que vous voulez changer en d'autres caractères. Ce n'est pas idéal, mais vous pouvez spécifier tous les caractères que vous voulez enlever, c'est-à-dire tous les caractères non numériques disponibles ...

(Oui, c'est une longue liste, une très longue liste, c'est pourquoi je dis ce n'est pas idéal)

TRADUIRE ('data', 'abc ... XYZ,/\ <> |.? [etc.]', ' «)

Sinon, vous devez créer un utilisateur défini fonction pour rechercher le numéro. Il y a quelques alternatives pour cela.

  1. Cochez chaque caractère un par un et conservez-le uniquement s'il s'agit d'un caractère numérique.

  2. Si vous savez ce qui précède le numéro et ce qui suit le numéro, vous pouvez rechercher ceux-ci et garder ce qui est entre ...

-1

Pour élaborer sur suggeston de Dems, l'approche que j'ai utilisé est une fonction définie par l'utilisateur scalaire (UDF) qui accepte une chaîne alphanumérique et itère récursivement à travers la chaîne (un octet par itération) et supprime les caractères non numériques de la sortie. L'expression récursive génère une ligne par itération, mais seule la dernière ligne est conservée et renvoyée à l'application appelante.

+0

C'est horriblement lent. – Hogan

4

Je sais que ce fil est vieux, et l'OP n'a pas besoin de la réponse, mais j'ai dû comprendre cela avec quelques indices de ceci et d'autres threads. Ils semblent tous manquer la réponse exacte.

La façon simple de faire ceci est TRANSLATE tous les caractères inutiles à un seul caractère, puis REPLACE ce seul caractère avec une chaîne vide.

DATA = 'Nowshak 7,485 m' 

# removes all characters, leaving only numbers 
REPLACE(TRANSLATE(TRIM(DATA), '_____________________________________________________________________________________________', ' abcdefghijklmnopqrstuvwzyaABCDEFGHIJKLMNOPQRSTUVWXYZ`[email protected]#$%^&*()-_=+\|[]{};:",.<>/?'), '_', '') 
=> '7485' 

Pour briser la commande TRANSLATE:

TRANSLATE(FIELD or String, <to characters>, <from characters>) 

par exemple

DATA = 'Sample by John' 

TRANSLATE(DATA, 'XYZ', 'abc') 
=> a becomes X, b becomes Y, c becomes Z 
=> 'SXmple Yy John' 

** Remarque: Je ne peux pas parler de performance ou de compatibilité de version. Je suis sur une version 9.x de DB2, et nouveau à la technologie. J'espère que cela aide quelqu'un.

+0

Vous n'avez pas besoin du 'REPLACE' ici, si le premier paramètre est' '' ', il supprimera tous ces caractères. Vous pouvez également utiliser la fonction 'UPPER' pour ne pas avoir à lister les caractères en minuscules. – Hogan

+0

@Hogan, 'TRANSLATE()' nécessite le même nombre de caractères dans le second paramètre que dans le troisième, donc le 'REPLACE' est requis (au moins sur ma version 9.x de DB2). En outre, l'utilisation de 'UPPER()' fonctionnerait, et simplifie la commande translate, mais je ne suis pas sûr que ce soit plus efficace dans l'ensemble. –

+0

Regardez ici le dernier exemple, il supprime le 'u' http://www.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000862. html Utilisez-vous une version antérieure à 9.7? :) donc 'TRADUIRE (x, '1234567890', '1234567890 ....')' fonctionnerait bien. – Hogan

Questions connexes