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


123

Я бачу, що в MySQL є Cast()і Convert()функції для створення цілих чисел із значень, але чи є спосіб перевірити, чи є значення цілим числом? Щось на зразок is_int()PHP - це те, що я шукаю.


2
так сумно, що ми повинні створити функцію is_int () в Mysql
Yuda Prawira

Відповіді:


214

Я припускаю, що ви хочете перевірити значення рядка. Один приємний спосіб - це оператор REGEXP, який відповідає рядку звичайному виразу. Просто робіть

select field from table where field REGEXP '^-?[0-9]+$';

це досить швидко. Якщо ваше поле числове, просто перевіряйте на

ceil(field) = field

замість цього.


4
Тест 'ceil (field) = field' є приємною ідеєю, але, як вказував @Jumpy, він не вдається на нечислових даних: SELECT ceil ('four') = 'four'; -> 1
Меттью Корнелл

3
@MatthewCornell, Він сказав, якщо ваше поле числове. Ось так ви можете перевірити, чи число є цілим числом. Він не працюватиме на рядках, тому перший варіант є.
Malfist

Якщо дані можуть містити пробіл, це не вдасться. Розгляньте тестування обрізки (поля), можливо, з додатковим аргументом для видалення нових рядків.
Майкл Гразебрук

дані є числовими, вони також можуть робити це: select ((поле% 1) = 0);
ThiamTeck

Дякую, але за числове порівняння, я думаю, вам цього не потрібно (strcmp (ceil (field), field))
Алан Діксон

14

Зрівняйте його з регулярним виразом.

cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488, як цитується нижче:

Re: пункт IsNumeric () в MySQL ??
Опублікував: kevinclark ()
Дата: 08 серпня 2005 р. 13:01


Я згоден. Ось функція, яку я створив для MySQL 5:

CREATE FUNCTION IsNumeric (sIn varchar(1024)) RETURNS tinyint
RETURN sIn REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$';


Це дає можливість на початку необов'язковий знак плюс / мінус, одну необов'язкову десяткову точку та інші числові цифри.


Дякуємо, ваше рішення піклується і про десяткові місця
Ананда,

12

Припустимо, у нас стовпчик з буквено-цифровим полем, що містить записи

a41q
1458
xwe8
1475
asde
9582
.
.
.
.
.
qe84

і ви хочете найвищого числового значення з цього колонки db (в даному випадку це 9582), тоді цей запит допоможе вам

SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'

1
'10000' вище, але ваш запит все одно поверне '9582' .
Пол Шпігель

8

Ось просте рішення для нього, якщо припустити, що тип даних є varchar

select * from calender where year > 0

Він повернеться істинним, якщо рік буде числовим, а неправдивим


29
У варшарі це також повернеться істиною, якщо перший символ буде числовим.
ТуК

Не помічав цього. під голосування ваш коментар :)
Jayjitraj

8

Це також працює:

CAST( coulmn_value AS UNSIGNED ) // will return 0 if not numeric string.

наприклад

SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0

11
що про те SELECT CAST('12a34' AS UNSIGNED), що повертає 12?
Майк C

1
Це чудово працює, якщо вам потрібно перевірити наявність нечислових елементів, це заслуговує на більше +1. Інші відповіді важче повернути тест, щоб знайти нечислові елементи.
DrCord

1
@DrCord це не працює для описаного Майком С, тому дуже ненадійний
Jontro

4

Щоб перевірити, чи є значення Int в Mysql, ми можемо використовувати наступний запит. Цей запит дасть рядки зі значеннями Int

SELECT col1 FROM table WHERE concat('',col * 1) = col;

Також буде вибрано не цілі числа (наприклад, "3.5" ).
Пол Шпігель

4

Найкраще, що я міг придумати змінну, - це поєднання з функціями MySQL CAST()та LENGTH().
Цей метод буде працювати над типами даних рядків, цілих чисел, подвійних / плаваючих.

SELECT (LENGTH(CAST(<data> AS UNSIGNED))) = (LENGTH(<data>)) AS is_int

див. демонстраційну версію http://sqlfiddle.com/#!9/ff40cd/44

не вдасться, якщо стовпець має одне значення символу. якщо стовпець має значення 'A', тоді Cast ('A' як UNSIGNED) буде оцінювати до 0, а LENGTH (0) буде 1. так LENGTH (Cast ('A' як UNSIGNED)) = LENGTH (0) буде оцінено до 1 = 1 => 1

Справжній Waqas Malik повністю задумався перевірити цю справу. пластир є.

SELECT <data>, (LENGTH(CAST(<data> AS UNSIGNED))) = CASE WHEN CAST(<data> AS UNSIGNED) = 0 THEN CAST(<data> AS UNSIGNED) ELSE (LENGTH(<data>)) END AS is_int;

Результати

**Query #1**

    SELECT 1, (LENGTH(CAST(1 AS UNSIGNED))) = CASE WHEN CAST(1 AS UNSIGNED) = 0 THEN CAST(1 AS UNSIGNED) ELSE (LENGTH(1)) END AS is_int;

| 1   | is_int |
| --- | ------ |
| 1   | 1      |

---
**Query #2**

    SELECT 1.1, (LENGTH(CAST(1 AS UNSIGNED))) = CASE WHEN CAST(1.1 AS UNSIGNED) = 0 THEN CAST(1.1 AS UNSIGNED) ELSE (LENGTH(1.1)) END AS is_int;

| 1.1 | is_int |
| --- | ------ |
| 1.1 | 0      |

---
**Query #3**

    SELECT "1", (LENGTH(CAST("1" AS UNSIGNED))) = CASE WHEN CAST("1" AS UNSIGNED) = 0 THEN CAST("1" AS UNSIGNED) ELSE (LENGTH("1")) END AS is_int;

| 1   | is_int |
| --- | ------ |
| 1   | 1      |

---
**Query #4**

    SELECT "1.1", (LENGTH(CAST("1.1" AS UNSIGNED))) = CASE WHEN CAST("1.1" AS UNSIGNED) = 0 THEN CAST("1.1" AS UNSIGNED) ELSE (LENGTH("1.1")) END AS is_int;

| 1.1 | is_int |
| --- | ------ |
| 1.1 | 0      |

---
**Query #5**

    SELECT "1a", (LENGTH(CAST("1.1" AS UNSIGNED))) = CASE WHEN CAST("1a" AS UNSIGNED) = 0 THEN CAST("1a" AS UNSIGNED) ELSE (LENGTH("1a")) END AS is_int;

| 1a  | is_int |
| --- | ------ |
| 1a  | 0      |

---
**Query #6**

    SELECT "1.1a", (LENGTH(CAST("1.1a" AS UNSIGNED))) = CASE WHEN CAST("1.1a" AS UNSIGNED) = 0 THEN CAST("1.1a" AS UNSIGNED) ELSE (LENGTH("1.1a")) END AS is_int;

| 1.1a | is_int |
| ---- | ------ |
| 1.1a | 0      |

---
**Query #7**

    SELECT "a1", (LENGTH(CAST("1.1a" AS UNSIGNED))) = CASE WHEN CAST("a1" AS UNSIGNED) = 0 THEN CAST("a1" AS UNSIGNED) ELSE (LENGTH("a1")) END AS is_int;

| a1  | is_int |
| --- | ------ |
| a1  | 0      |

---
**Query #8**

    SELECT "a1.1", (LENGTH(CAST("a1.1" AS UNSIGNED))) = CASE WHEN CAST("a1.1" AS UNSIGNED) = 0 THEN CAST("a1.1" AS UNSIGNED) ELSE (LENGTH("a1.1")) END AS is_int;

| a1.1 | is_int |
| ---- | ------ |
| a1.1 | 0      |

---
**Query #9**

    SELECT "a", (LENGTH(CAST("a" AS UNSIGNED))) = CASE WHEN CAST("a" AS UNSIGNED) = 0 THEN CAST("a" AS UNSIGNED) ELSE (LENGTH("a")) END AS is_int;

| a   | is_int |
| --- | ------ |
| a   | 0      |

дивіться демонстрацію


не вдасться, якщо стовпець має одне значення символу. якщо стовпець має значення 'A', тоді Cast ('A' як UNSIGNED) буде оцінювати до 0, а LENGTH (0) буде 1. так LENGTH (Cast ('A' як UNSIGNED)) = LENGTH (0) буде оцінено до 1 = 1 => 1
Вакас Малик

Спасибі за коментар , що випадок був дійсно неперевіреною @WaqasMalik працює і тестування патча прямо зараз .. що - щось на зразокSELECT "a", (LENGTH(CAST("a" AS UNSIGNED))) = CASE WHEN CAST("a" AS UNSIGNED) = 0 THEN CAST("a" AS UNSIGNED) ELSE (LENGTH("a")) END AS is_int;
Raymond Nijland

Це таке круте рішення. Я думаю, що це не вдається для негативних цілих чисел, чи змінює щось суттєве (у кращих випадках), щоб переключити ваше рішення на підписані цілі числа? Я тестував, використовуючи вашу загадку як основу. set @val = '1.'; SELECT @val, LENGTH(CAST(@val AS SIGNED)) = IF(CAST(@val AS SIGNED) = 0, CAST(@val AS SIGNED), LENGTH(@val)) AS is_int;Цей рефакторинг обробляє всі вищезазначені випадки, але навіть моє коригування не справляється з -1.0 або '-1'. Знову ж таки, супер класне рішення.
spen.smith

3

А як на рахунок:

WHERE table.field = "0" or CAST(table.field as SIGNED) != 0

для перевірки чисельності та кордону:

WHERE table.field != "0" and CAST(table.field as SIGNED) = 0

1
CAST (table.field)! = 0 не працюватиме, оскільки йому потрібно видавати тип.
Ріад

Це чудово працює, якщо вам потрібно перевірити наявність нечислових елементів, це заслуговує на більше +1. Інші відповіді важче повернути тест, щоб знайти нечислові елементи.
DrCord

Це не працює для чисел, таких як "0000", "0" (пробіл) та "7x" (що вважається числом).
Майкл Гразебрук

@MichaelGrazebrook Я вважаю, що ви могли б зробити повторний досвід для перших двох випадків. "7x" вважається числом? "0x7" - це число, але 7x?
Том Ожер

1
@Tom Auger: Ще одна відповідь стосувалася рішень типу регулярних виразів. Що я мав на увазі під «7x вважається числом», це те, що це твердження є істинним: select 7 = '7q'
Майкл Гразебрук

1

Я спробував використовувати перелічені вище регулярні вирази, але вони не працюють для наступного:

SELECT '12 INCHES' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...

Вище буде повернено 1( TRUE), що означає тест рядка '12 ДІНЧ 'проти регулярного виразу вище, повертається TRUE. Це схоже на число, засноване на регулярному виразі, використаному вище. У цьому випадку, оскільки 12 знаходиться на початку рядка, регулярний вираз інтерпретує його як число.

Далі поверне правильне значення (тобто 0), оскільки рядок починається з символів замість цифр

SELECT 'TOP 10' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...

Наведене повернеться 0( FALSE), оскільки початок рядка є текстовим, а не числовим.

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


2
Це неправильно. Ви тестували це? Коли я запускаю ваш перший приклад, він повертається FALSE, як і очікувалося, тому що регулярний вираз закінчується тим, $що означає кінець рядка, тому він перевіряє лише числа, як задумав автор.
spikyjt

1

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

WHERE concat('',fieldname * 1) != fieldname 

можуть виникнути обмеження, коли ви потрапляєте на більші числа NNNNE + -


Схоже, це не працює для одиночних струнних рядківset @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;
spen.smith,

0

для мене єдине, що працює:

CREATE FUNCTION IsNumeric (SIN VARCHAR(1024)) RETURNS TINYINT
RETURN SIN REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$';

від kevinclark всі інші непотрібні для мене речі у випадку 234jk456або12 inches

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