Визначте, чи значення є числом у MySQL


159

Чи є спосіб визначити, чи є значення числом у запиті MySQL? Як от

SELECT * 
FROM myTable 
WHERE isANumber(col1) = true

Я перевірив стратегію 1 * col = col, але якимось чином виходить з ладу, коли запит викликається через PHP (повертає істину, коли не повинен). Однак у phpMyAdmin хак працює. Це означає, що мій тест поводиться так, як очікувалося. Придбати мою програму не потрібно.
Jahaziel

Відповіді:


250

Це повинно працювати в більшості випадків.

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

Це не працює для нестандартних номерів, як-от

  • 1e4
  • 1.2e5
  • 123. (кінцевий десятковий)

Дякую. На жаль, мені це потрібно, щоб визнати, що 123 - це число, але 123X - це не так.
Урбікоз

1
@ Річард, я просто прочитав винятки, які ви дали. Думав, ти мав на увазі персонажа "е". Я бачу, що ти маєш на увазі зараз.
Урбікоз

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

Я знаю, що це стара публікація, але я використовую цей метод у своєму запиті. Але у мене проблема, вона виявляє "2-Power" як "2", що спричиняє неприємності, оскільки цього не слід робити. Будь-яка ідея?
GRosay

1
Для останнього та ведучого нулів (наприклад, 023.12000): concat ('', col1 * 1) = '0' АБО concat ('', col1 * 1) = IF (LOCATE ('.', Col1), TRIM (BOTH ' 0 'ВІД col1), TRIM (ЛІДИНГ' 0 'ВІД col1));
Франсуа Бретон

299

Ви також можете використовувати Regular Expression ... це було б так:

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

Довідка: http://dev.mysql.com/doc/refman/5.1/en/regexp.html


70
ВИБІР * ІЗ myTable WHERE col1 REGEXP '^ [0-9] + $';
Дмитро Козьменко

7
Прийнята відповідь дійсно розумна, але ця відповідь є більш прямою, і я думаю, це має бути прийнятим рішенням.
pedromanoel

21
У випадку "не відповідає": WHERE col1 NOT REGEXP...а для випадку, коли у вас може бути десяткова крапка, використовуйте регулярний вираз:^[0-9\.]+$
Роббі Аверилл

2
Також не працюватиме для наукових позначень, працює лише для інтів
Девід Уілкінс

1
Людям, які ніколи не користувалися Regex migth, важко читати, але ви можете робити з ним справді чудові та короткі речі
Оллі,

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'


Мені подобається цей підхід краще, тому що він чіткіший і менш хакітний, ніж фокус конкатенації. Дякую!
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

@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

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

- ви можете вдосконалити функцію прийому десяткових знаків, наукових позначень тощо ...

Перевага використання UDF полягає в тому, що ви можете використовувати його в лівій або правій частині порівняння "де застереження". це значно спрощує ваш SQL перед відправкою в базу даних:

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

сподіваюся, що це допомагає.


5

Ще одна альтернатива, яка здається швидшою, ніж REGEXP на моєму комп’ютері, - це

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

Це дозволить вибрати всі рядки, де col1 починається з числового значення.


2
А як бути, якщо значення дорівнює нулю?
Урбікоз

1
Я думаю, ви можете просто додати, AND col1<>0щоб обробити цей виняток.
Урбікоз

Це правда, що вона не працює для нульових значень, але вона прекрасно працює для прокладених чисел, наприклад, 004. Прийнята відповідь не працює для прокладених чисел
Аббас,

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

Я отримую помилковий позитив для '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'ІСТИНА
Пол Шпігель

3

Я рекомендую: якщо ваш пошук простий, ви можете використовувати `

column*1 = column

`Оператор цікавий :) - робота і швидша, ніж на полях varchar / char

ВИБІР * ІЗ 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повернути істину?
Grzegorz Smulko

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), "")


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.