Определить, является ли значение числом в MySQL


159

Есть ли способ определить, является ли значение числом в запросе MySQL? Такие как

SELECT * 
FROM myTable 
WHERE isANumber(col1) = true

Я проверил стратегию 1 * col = col, но почему-то она терпит неудачу, когда запрос вызывается через PHP (возвращая true, когда это не должно). В phpMyAdmin однако взлом работает. Это означает, что мой тест ведет себя как ожидалось, покупка моего приложения - нет.
Джахазиил

Ответы:


251

Это должно работать в большинстве случаев.

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

Это не работает для нестандартных номеров, таких как

  • 1e4
  • 1.2e5
  • 123. (конечный десятичный)

Спасибо. К сожалению, мне нужно признать, что 123 - это число, а 123X - нет.
Urbycoz

1
@ Ричард, я только что прочитал твои исключения. Думал, ты имел в виду символ "е". Теперь я понимаю, что вы имеете в виду.
Urbycoz

Лидирующие нули не являются проблемой для ловкого разработчика sql --- trim (ведущий 0 из col1)
pimbrouwers

Я знаю, что это старый пост, но я использую этот метод в своем запросе. Но у меня есть проблема, он обнаруживает «2-Power» как «2», вызывая проблемы, поскольку он не должен этого делать. Любая идея ?
GRosay

1
Для конечных и ведущих нулей (например, 023.12000): concat ('', col1 * 1) = '0' ИЛИ ​​concat ('', col1 * 1) = IF (LOCATE ('.', Col1), TRIM (ОБА) 0 'ОТ col1), TRIM (ВЕДУЩИЙ' 0 'ОТ col1));
Франсуа Бретон

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] + $';
Дмитрий Козьменко

7
Принятый ответ действительно умный, но этот ответ более прямой, и я думаю, что это должно быть принятое решение.
Pedromanoel

21
Для случая «не совпадает»: WHERE col1 NOT REGEXP...и для случая, когда вы можете иметь десятичную точку, используйте регулярное выражение:^[0-9\.]+$
Робби Аверилл

2
Также не работает для научной нотации, работает только для целых
Дэвид Уилкинс

1
Regex migth будет трудно читать людям, которые никогда не использовали его, но вы можете делать с ним действительно хорошие и короткие вещи
Olli

56

Если ваши данные «test», «test0», «test1111», «111test», «111»

Чтобы выбрать все записи, где данные являются простыми int:

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»


Мне нравится этот подход лучше, потому что он более четкий и менее "хакерский", чем трюк с конкатенацией. Спасибо!
brokethebuildagain

8
Не работает для отрицательных значений. Я бы исправил предложенное регулярное выражение следующим образом:REGEXP '^[+\-]?[0-9]+\\.?[0-9]*$'
Николас

Я бы сказал, что символ «+» не является необходимым, вы можете использовать только «-?», Но если вы хотите использовать его, вы должны его избежать (и символ «-» не нужно экранировать) ,
Т. Корнер

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
Отлично! Единственный ответ, который на самом деле охватывает все основания. Должен быть принятый ответ.
Дом

10

Возвращает числовые строки

Я нашел решение с помощью следующего запроса и работает для меня:

SELECT * FROM myTable WHERE col1 > 0;

Этот запрос возвращает строки, имеющие только столбец с номерами больше нуля, которые col1

Возвращает нечисловые строки

если вы хотите проверить столбец не числовой, попробуйте этот с помощью трюка ( !col1 > 0):

SELECT * FROM myTable WHERE !col1 > 0;

Это не работает, если у вас есть строка, которая начинается с цифры «123abc», она будет возвращена в вашем выражении с числовыми строками, а не в нечисловом выражении.
Стефен

@JStephen Ты прав! Поскольку SELECT * FROM myTable WHERE col1 = 123;запрос будет возвращать строки, даже значение столбца123abc
Bora

9

Этот ответ похож на Дмитрия, но он допускает десятичные, а также положительные и отрицательные числа.

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

выберите isnumber (mycol) mycol1, col2, colx из таблицы; - вернет 1 и 0 для столбца mycol1

- Вы можете улучшить функцию, чтобы принимать десятичные дроби, научные записи и т. д ...

Преимущество использования UDF заключается в том, что вы можете использовать его слева или справа от сравнения «где предложение». это значительно упрощает ваш SQL перед отправкой в ​​базу данных:

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

надеюсь это поможет.


5

Еще одна альтернатива, которая кажется быстрее чем REGEXP на моем компьютере:

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

Это выберет все строки, где col1 начинается с числового значения.


2
А что если значение равно нулю?
Urbycoz

1
Я думаю, вы могли бы просто добавить, AND col1<>0чтобы обработать это исключение.
Urbycoz

Это правда, что он не работает для нулевых значений, но он отлично работает для дополненных чисел, например, 004. Принятый ответ не работает для дополненных чисел
Аббас

Я думаю, что это лучший способ проверить номера. Просто нам нужно добавить оператор OR для проверки нуля, как SELECT * FROM myTable WHERE col1 * 0! = Col1 OR col1 = '0';
Бину Раман

Я получаю ложное срабатывание '1a'. Кстати: это эквивалентно 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'ИСТИНА
Пол Шпигель

3

Я рекомендую: если ваш поиск прост, вы можете использовать `

column*1 = column

Оператор интересный :) работает и быстрее чем на полях varchar / char

SELECT * FROM myTable WHERE column * 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возвращает истину?
Гжегож Смулько

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

ofcourse sign (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), "")


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.