web-dev-qa-db-fra.com

Détecter si la valeur est un nombre dans MySQL

Existe-t-il un moyen de détecter si une valeur est un nombre dans une requête MySQL? Tel que

SELECT * 
FROM myTable 
WHERE isANumber(col1) = true
137
Urbycoz

Cela devrait fonctionner dans la plupart des cas.

SELECT * FROM myTable WHERE concat('',col1 * 1) = col1

Cela ne fonctionne pas pour les numéros non standard comme

  • 1e4
  • 1.2e5
  • 123. (décimal de fin)
223
RichardTheKiwi

Vous pouvez aussi utiliser une expression régulière ... ce serait comme:

SELECT * FROM myTable WHERE col1 REGEXP '^[0-9]+$';

Référence: http://dev.mysql.com/doc/refman/5.1/en/regexp.html

260
T. Corner

Si vos données sont 'test', 'test0', 'test1111', '111test', '111'

Pour sélectionner tous les enregistrements où les données sont un simple int:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '^[0-9]+$';

Résultat: '111'

(Dans regex, ^ signifie commencer et $ signifie fin)

Pour sélectionner tous les enregistrements contenant un nombre entier ou décimal:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '^[0-9]+\\.?[0-9]*$'; - for 123.12

Résultat: '111' (identique au dernier exemple)

Enfin, pour sélectionner tous les enregistrements contenant un numéro, utilisez ceci:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '[0-9]+';

Résultat: 'test0' et 'test1111' et '111test' et '111'

51
Dmitriy Kozmenko

Cette réponse est similaire à celle de Dmitry, mais elle autorisera les nombres décimaux ainsi que les nombres positifs et négatifs.

select * from table where col1 REGEXP '^[[:digit:]]+$'
9
Devpaq
SELECT * FROM myTable
WHERE col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$'

Correspondra également aux décimales signées (comme - 1.2, +0.2, 6., 2e9, 1.2e-10 ).

Tester:

drop table if exists myTable;
create table myTable (col1 varchar(50));
insert into myTable (col1) 
  values ('00.00'),('+1'),('.123'),('-.23e4'),('12.e-5'),('3.5e+6'),('a'),('e6'),('+e0');

select 
  col1,
  col1 + 0 as casted,
  col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$' as isNumeric
from myTable;

Résultat:

col1   |  casted | isNumeric
-------|---------|----------
00.00  |       0 |         1
+1     |       1 |         1
.123   |   0.123 |         1
-.23e4 |   -2300 |         1
12.e-5 | 0.00012 |         1
3.5e+6 | 3500000 |         1
a      |       0 |         0
e6     |       0 |         0
+e0    |       0 |         0

démo

6
Paul Spiegel

retourne des lignes numériques

J'ai trouvé la solution avec la requête suivante et fonctionne pour moi:

SELECT * FROM myTable WHERE col1 > 0;

Cette requête renvoie des lignes ayant uniquement une colonne dont le nombre est supérieur à zéro et que col1

retourne des lignes non numériques

si vous voulez vérifier la colonne non numérique, essayez celle-ci avec l'astuce (!col1 > 0):

SELECT * FROM myTable WHERE !col1 > 0;
5
Bora

Une autre alternative qui semble plus rapide que REGEXP sur mon ordinateur est

SELECT * FROM myTable WHERE col1*0 != col1;

Cela sélectionnera toutes les lignes où col1 commence par une valeur numérique.

5
Stian Hvatum

utiliser un UDF (fonction définie par l'utilisateur).

CREATE FUNCTION isnumber(inputValue VARCHAR(50))
  RETURNS INT
  BEGIN
    IF (inputValue REGEXP ('^[0-9]+$'))
    THEN
      RETURN 1;
    ELSE
      RETURN 0;
    END IF;
  END;

Puis quand vous interrogez

select isnumber('383XXXX') 

--retours 0

select isnumber('38333434') 

--retours 1

sélectionnez isnumber (mycol) mycol1, col2, colx de tablex; - retournera 1 et 0 pour la colonne mycol1

--vous pouvez améliorer la fonction pour prendre des décimales, une notation scientifique, etc.

L'avantage d'utiliser un fichier UDF est que vous pouvez l'utiliser à gauche ou à droite de votre comparaison "clause". ceci simplifie grandement votre SQL avant d'être envoyé à la base de données:

 SELECT * from tablex where isnumber(columnX) = isnumber('UnkownUserInput');

j'espère que cela t'aides.

5
Hugo R

Il manque toujours cette version simple:

SELECT * FROM myTable WHERE `col1` + 0 = `col1`

(l'addition devrait être plus rapide que la multiplication)

Ou la version la plus lente pour continuer à jouer:

SELECT *, 
CASE WHEN `col1` + 0 = `col1` THEN 1 ELSE 0 END AS `IS_NUMERIC` 
FROM `myTable`
HAVING `IS_NUMERIC` = 1
4
Jirka Kopřiva

Je recommande: si votre recherche est simple, vous pouvez utiliser `

column*1 = column

`opérateur intéressant :) est le travail et plus rapide que sur les champs varchar/char

SELECT * FROM myTable WHERE colonne * 1 = colonne;

ABC*1 => 0 (NOT EQU **ABC**)
AB15*A => 15 (NOT EQU **AB15**)
15AB => 15 (NOT EQU **15AB**)
15 => 15 (EQUALS TRUE **15**)
3
Ferhat KOÇER
SELECT * FROM myTable WHERE sign (col1)!=0

bien sûr, le signe (0) vaut zéro, mais vous pouvez alors restreindre votre requête à ...

SELECT * FROM myTable WHERE sign (col1)!=0 or col1=0

UPDATE: Ce n'est pas fiable à 100%, parce que "1abc" renverrait le signe 1, mais "ab1c" renverrait zéro ... cela ne peut donc fonctionner que pour du texte ne commençant pas par des chiffres.

1
Miguel

J'ai trouvé que cela fonctionne assez bien

if(col1/col1= 1,'number',col1) AS myInfo
0
Mike The Elf

vous pouvez faire en utilisant CAST

  SELECT * from tbl where col1 = concat(cast(col1 as decimal), "")
0
sumit