Определить, является ли значение числом в 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.