检测值是否为MySQL中的数字


159

有没有一种方法可以检测MySQL查询中的值是否为数字?如

SELECT * 
FROM myTable 
WHERE isANumber(col1) = true

我已经测试了1 * col = col策略,但是当通过PHP调用查询时,它以某种方式失败了(当它不应该返回true时)。但是,在phpMyAdmin中,该hack有效。这意味着我的测试行为符合预期,但购买我的应用程序却没有。
Jahaziel

Answers:


250

在大多数情况下,这应该可行。

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

它不适用于非标准数字,例如

  • 1e4
  • 1.2e5
  • 123. (十进制)

谢谢。不幸的是,我需要它来识别123是一个数字,但123X不是。
Urbycoz

1
@ Richard-我刚刚读了您给出的例外。以为您的意思是字符“ e”。我明白你的意思了。
Urbycoz'2

对于
熟练的

我知道这是一个旧帖子,但是我在查询中使用了此方法。但是我有一个问题,它检测到“ 2-Power”为“ 2”而引起麻烦,因为它不应该这样做。任何想法 ?
GRosay

1
对于尾随零和前零(例如023.12000):concat('',col1 * 1)='0'或concat('',col1 * 1)= IF(LOCATE('。',col1),TRIM(BOTH' 0'FROM col1),TRIM(从col1)领先'0');
弗朗索瓦·布雷顿

299

您也可以使用正则表达式...就像:

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

参考: http : //dev.mysql.com/doc/refman/5.1/en/regexp.html


70
SELECT * FROM myTable WHERE col1 REGEXP'^ [0-9] + $';
Dmitriy Kozmenko 2013年

7
公认的答案确实很聪明,但是这个答案更直接,我认为这应该是公认的解决方案。
pedromanoel 2013年

21
对于“不匹配”:WHERE col1 NOT REGEXP...和可能带有小数点的情况,请使用正则表达式:^[0-9\.]+$
Robbie Averill 2013年

2
同样不适用于科学计数法,仅适用于整数
David Wilkins

1
对于从未使用过Regex migth的人来说,它很难读懂,但是您可以用它做真正的伟大和短暂的事情
Olli

56

如果您的数据是“ test”,“ test0”,“ test1111”,“ 111test”,“ 111”

要选择数据为简单整数的所有记录,请执行以下操作:

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

结果:“ 111”

(在正则表达式中,^表示开始,$表示结束)

要选择存在整数或十进制数字的所有记录:

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

结果:“ 111”(与上一个示例相同)

最后,要选择存在数字的所有记录,请使用以下命令:

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

结果:“ test0”和“ test1111”以及“ 111test”和“ 111”


我比较喜欢这种方法,因为它比连接技巧更清晰,“黑客”也少。谢谢!
重新建造

8
不适用于负值。我将提议的正则表达式修改如下:REGEXP '^[+\-]?[0-9]+\\.?[0-9]*$'
Nicolas

我会说“ +”符号不是必需的,您可以只使用“-?”,但是如果要使用它,则应对其进行转义(并且不必对“-”符号进行转义) 。
T. Corner,

13
SELECT * FROM myTable
WHERE col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$'

也将匹配带符号的小数(例如-1.2,+ 0.2、6、2e9、1.2e-10)。

测试:

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;

结果:

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

演示版


3
完善!只有真正涵盖所有基础的答案。应该是公认的答案。
Dom,

10

返回数字行

我通过以下查询找到了解决方案并为我工作:

SELECT * FROM myTable WHERE col1 > 0;

该查询返回的行仅具有大于零的数字列 col1

返回非数字行

如果要检查非数字列,请尝试使用技巧(!col1 > 0):

SELECT * FROM myTable WHERE !col1 > 0;

这不起作用,如果您有一个以数字“ 123abc”开头的字符串,它将在您的数字行语句而不是非数字语句中返回。
JStephen

@JStephen你说的对!因为SELECT * FROM myTable WHERE col1 = 123;查询将返回行,甚至col值为123abc
Bora

9

这个答案类似于德米特里(Dmitry),但是它将允许小数以及正数和负数。

select * from table where col1 REGEXP '^[[:digit:]]+$'

8

使用UDF(用户定义函数)。

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

然后当你查询

select isnumber('383XXXX') 

-返回0

select isnumber('38333434') 

-返回1

从tablex中选择isnumber(mycol)mycol1,col2,colx;-将为mycol1列返回1和0

-您可以增强采用小数,科学计数法等的功能...

使用UDF的优点是可以在“ where子句”比较的左侧或右侧使用它。这在将SQL发送到数据库之前大大简化了您的SQL:

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

希望这可以帮助。


5

在我的计算机上似乎比REGEXP更快的另一种选择是

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

这将选择col1以数字值开头的所有行。


2
如果值为零怎么办?
Urbycoz 2014年

1
我想您可以添加AND col1<>0以处理该异常。
Urbycoz 2014年

的确,它不能用于零值,但可以完美地用于带填充数字,例如004。接受的答案不适用于带填充数字
Abbas

我认为这是检查数字的最佳方法。只是我们需要添加一个OR语句来检查零,如SELECT * FROM myTable WHERE col1 * 0!= col1 OR col1 ='0';
Binu Raman

我对表示不满意'1a'。BTW:这是相当于WHERE col1 <> 0- rextester.com/DJIS1493
保罗·施皮格尔

4

仍然缺少此简单版本:

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

(相乘应更快)

或最慢版本以供进一步播放:

SELECT *, 
CASE WHEN `col1` + 0 = `col1` THEN 1 ELSE 0 END AS `IS_NUMERIC` 
FROM `myTable`
HAVING `IS_NUMERIC` = 1

3
除非我有误解,否则MySQL会将任何字符串转换为0,因此这不会区分字符串和数字,两者都将返回相同的值。
伊万·麦卡

3
'a' + 0 = 'a'是真的
Paul Spiegel

3

我建议:如果您的搜索很简单,则可以使用`

column*1 = column

`有趣的操作符:)是工作的,并且比varchar / char字段更快

SELECT * FROM myTable WHERE列* 1 =列;

ABC*1 => 0 (NOT EQU **ABC**)
AB15*A => 15 (NOT EQU **AB15**)
15AB => 15 (NOT EQU **15AB**)
15 => 15 (EQUALS TRUE **15**)

1
您是否知道在MySQL select 'aaa123' >= 0和中都 select '123aaa' >= 0返回true?
Grzegorz Smulko '16

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

当然符号(0)为零,但是您可以将查询限制为...

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

更新:这不是100%可靠的,因为“ 1abc”将返回1的符号,但是“ ab1c”将返回零...因此,这仅适用于非以数字开头的文本。


0

你可以使用 CAST

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.