En el mundo ideal, los campos tipo cadena (string) en una base de datos contiene una mezcla de caracteres alfanuméricos. También puede pasar que a veces dichos campos pasen a solo tener números. Según el diseño que se haya planeado eso puede estar bien pero en mi caso particular, era un error que unos campos tuvieran valores como «1» en vez de «My pain is bad».
Para arreglar dicho detalle tuve que crear y ejecutar una serie de rake tasks (proyecto Ruby on Rails) y encontrar aquellos valores solo número en strings fue complicado pero lo logré con SQL puro. Veamos.
La primera prueba fue esta:
SELECT id, form_id, content
FROM answers
WHERE content LIKE '%[0-9]%';
id | form_id | content
----+---------+---------
(0 rows)
No trajo resultados. Que raro. Cambié la torta y obtuve otros resultados:
SELECT id, form_id, content
FROM answers
WHERE content NOT LIKE '%[0-9]%'
LIMIT 10;
id | form_id | content
------+---------+--------------------------------------------------------------------------------------------------------------------------------
1339 | 6 | I have no pain at the moment
1341 | 6 | I can lift heavy weights but it gives extra pain
1342 | 6 | Pain prevents me from walking more than 1 mile
1343 | 6 | I can only sit in my favourite chair as long as I like
1344 | 6 | Pain prevents me from standing for more than 1 hour
1345 | 6 | My sleep is occasionally disturbed by pain
Así que por ahí no era la cuestión. La siguiente consulta sí que me dio resultados:
SELECT id,content,REGEXP_MATCHES(content, '[[:digit:]]')
FROM answers
WHERE option_choice_id IS NULL;
id | content | regexp_matches
------+----------------------------------------------------------------+----------------
1342 | Pain prevents me from walking more than 1 mile | {1}
1344 | Pain prevents me from standing for more than 1 hour | {1}
29 | My sleep is slightly disturbed (less than 1 hr sleepless) | {1}
24 | I can read as much as I want to with slight pain in my neck 2 | {2}
276 | 2 | {2}
287 | 3 | {3}
44 | Pain prevents me from walking more than 1/2 mile | {1}
Y aquí sí vemos los resultados que queríamos que son solo campos con datos numéricos (recuerda que queremos alfanuméricos solamente).
La clave está en la forma en cómo se indica lo que se quiere seleccionar.
REGEXP_MATCHES(content, '[[:digit:]]')
Esto lo encontré en Stack Overflow. La función regexp_matches
existe en PosgreSQL desde la versión 8.3 y nos devuelve registros donde la expresión regular aplique.
Puedes ver más sobre esta función en este sitio web.