Domanda

oI hanno una tabella di Teradata con circa 10 milioni di dischi in esso, che memorizza un campo ID numerico come varchar. ho bisogno di trasferire i valori in questo campo per una colonna bigint in un'altra tabella, ma non posso semplicemente dire cast (id_field come bigint) perché ottengo un errore carattere non valido. guardando attraverso i valori, trovo che ci potrebbe essere un personaggio in qualsiasi posizione nella stringa, quindi diciamo che la stringa è varchar (18) ho potuto filtrare le righe non valide in questo modo:

     where substr(id_field,1,1) not in (/*big,ugly array of non-numeric chars*/)
     and substr(id_field,2,1) not in (/*big,ugly array of non-numeric chars*/)

etc, etc... 

poi il cast avrebbe funzionato, ma questo non è fattibile nel lungo periodo. è lento e se la stringa ha 18 caratteri possibili, rende la query illeggibile. Come posso filtrare le righe che hanno un valore in questo campo che non espressi come bigint senza controllare ogni carattere individualmente per un array di caratteri non numerici?

I valori esempio potrebbe essere

   123abc464
   a2.3v65
   a_356087
   ........
   000000000
   BOB KNIGHT
   1235468099

i valori non seguono i modelli specifici, ho semplicemente bisogno di filtrare quelli che contengono dati ANY non numerici.           123456789 va bene, ma non è 123.abc_c3865 ...

È stato utile?

Soluzione

La cosa migliore che io abbia mai riuscito è questa:

where char2hexint(upper(id_field)) = char2hexint(lower(id_field))

Dal caratteri maiuscoli danno un valore esadecimale diverso per abbassare quelli di casi, questo farà sì che non si hanno i caratteri alfabetici, ma sarà ancora vi lascerà con sottolineatura, due punti e così via. Se questo non soddisfa le vostre esigenze, potrebbe essere necessario scrivere un'UDF.

Altri suggerimenti

A partire da TD14 Teradata ha aggiunto alcune funzioni, ora ci sono diversi modi, per esempio:.

WHERE RTRIM(col, '0123456789') = ''

Ma il modo più semplice è TO_NUMBER, che restituisce NULL per dati errati:

TO_NUMBER(col)

potremmo anche cercare di dividere i valori nel campo da qualche intero "se diviso allora deve essere un numero e se non e getta qualche errore, quindi deve avere un po 'di carattere ...." immagino che questo sarebbe molto velocemente ha appena matematica coinvolta ...

Ho affrontato lo stesso problema per cercare di escludere alfa personaggi di numeri civici indirizzo. Quanto segue funziona se non ti dispiace concatanating tutti i numeri numerici insieme ...... Controlla se la parte superiore di una stringa è uguale al minore della stringa, in tal caso si tratta di un numero, se non diventa nullo.

select cast(case when upper(substring('12E'from 1 for 1)) = lower(substring('12E'from 1 for 1)) then substring('12E'from 1 for 1) else null end ||
             case when upper(substring('12E'from 2 for 1)) = lower(substring('12E'from 2 for 1)) then substring('12E'from 2 for 1) else null end ||
             case when upper(substring('12E'from 3 for 1)) = lower(substring('12E'from 3 for 1)) then substring('12E'from 3 for 1) else null end ||
             case when upper(substring('12E'from 4 for 1)) = lower(substring('12E'from 4 for 1)) then substring('12E'from 4 for 1) else null end ||
             case when upper(substring('12E'from 5 for 1)) = lower(substring('12E'from 5 for 1)) then substring('12E'from 5 for 1) else null end ||
             case when upper(substring('12E'from 2 for 1)) = lower(substring('12E'from 2 for 1)) then substring('12E'from 2 for 1) else null end
             as integer) 

Provare a utilizzare questo segmento di codice

WHERE id_Field NOT LIKE '%[^0-9]%'

Ho trovato lins314159 risposta ad essere molto utile con un problema simile. Potrebbe essere un vecchio thread, ma per quello che vale, ho usato:

char2hexint (superiore (id_field)) = char2hexint (inferiore (id_field)) E substr (id_field, 1,1) IN ( '1' a '9')

per lanciare con successo i risultati rimanenti VARCHAR a INT

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top