Widzę, że w MySQL są Cast()i Convert()funkcje do tworzenia liczb całkowitych z wartości, ale czy istnieje sposób, aby sprawdzić, czy wartość jest liczbą całkowitą? Coś jakis_int() w PHP jest tym, czego szukam.
Widzę, że w MySQL są Cast()i Convert()funkcje do tworzenia liczb całkowitych z wartości, ale czy istnieje sposób, aby sprawdzić, czy wartość jest liczbą całkowitą? Coś jakis_int() w PHP jest tym, czego szukam.
Odpowiedzi:
Zakładam, że chcesz sprawdzić wartość ciągu. Jednym fajnym sposobem jest operator REGEXP, dopasowujący ciąg do wyrażenia regularnego. Po prostu zrób
select field from table where field REGEXP '^-?[0-9]+$';
to jest dość szybkie. Jeśli twoje pole jest liczbowe, po prostu przetestuj
ceil(field) = field
zamiast.
Dopasuj go do wyrażenia regularnego.
cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488, jak podano poniżej:
Re: Klauzula IsNumeric () w MySQL ??
Wysłane przez: kevinclark ()
Data: 08 sierpnia 2005 13:01
Zgadzam się. Oto funkcja, którą stworzyłem dla 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]+)$';
Pozwala to na opcjonalny znak plus / minus na początku, jeden opcjonalny separator dziesiętny i pozostałe cyfry.
Załóżmy, że mamy kolumnę z polem alfanumerycznym zawierającą wpisy takie jak
a41q
1458
xwe8
1475
asde
9582
.
.
.
.
.
qe84
i chcesz mieć najwyższą wartość liczbową z tej kolumny db (w tym przypadku jest to 9582), to ta kwerenda Ci pomoże
SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'
Oto proste rozwiązanie przy założeniu, że typ danych to varchar
select * from calender where year > 0
Zwróci wartość true, jeśli rok ma wartość liczbową, w przeciwnym razie fałsz
Działa to również:
CAST( coulmn_value AS UNSIGNED ) // will return 0 if not numeric string.
na przykład
SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0
SELECT CAST('12a34' AS UNSIGNED), co wraca 12?
Aby sprawdzić, czy wartość jest Int w MySQL, możemy użyć następującego zapytania. To zapytanie da wiersze z wartościami Int
SELECT col1 FROM table WHERE concat('',col * 1) = col;
Najlepsze, co mogłem wymyślić o zmiennej, to int to połączenie z funkcjami MySQL CAST()i LENGTH().
Ta metoda będzie działać na typach danych typu string, integer, double / floats.
SELECT (LENGTH(CAST(<data> AS UNSIGNED))) = (LENGTH(<data>)) AS is_int
zobacz demo http://sqlfiddle.com/#!9/ff40cd/44
nie powiedzie się, jeśli kolumna ma wartość jednego znaku. jeśli kolumna ma wartość „A”, to Cast („A” jako UNSIGNED) przyjmie wartość 0, a LENGTH (0) będzie równe 1., więc LENGTH (Cast („A” as UNSIGNED)) = LENGTH (0) będzie obliczane na 1 = 1 => 1
Prawdziwy Waqas Malik kompletnie nie mógł przetestować tej sprawy. poprawka jest.
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;
Wyniki
**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 |
zobacz demo
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;
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;Ta refaktoryzacja obsługuje wszystkie powyższe przypadki, ale nawet moja korekta nie obsługuje -1.0 lub -1. Znowu super fajne rozwiązanie.
Co powiesz na:
WHERE table.field = "0" or CAST(table.field as SIGNED) != 0
aby przetestować liczbowe i korelacyjne:
WHERE table.field != "0" and CAST(table.field as SIGNED) = 0
Próbowałem użyć wyrażeń regularnych wymienionych powyżej, ale nie działają one w następujących przypadkach:
SELECT '12 INCHES' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
Powyższe zwróci 1( TRUE), co oznacza, że test łańcucha „12 cali” w porównaniu z powyższym wyrażeniem regularnym, zwraca TRUE. Wygląda jak liczba na podstawie powyższego wyrażenia regularnego. W tym przypadku, ponieważ 12 znajduje się na początku ciągu, wyrażenie regularne interpretuje ją jako liczbę.
Poniższy kod zwróci właściwą wartość (tj. 0), Ponieważ ciąg zaczyna się od znaków zamiast cyfr
SELECT 'TOP 10' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
Powyższe zwróci 0( FALSE), ponieważ początek ciągu to tekst, a nie liczba.
Jeśli jednak masz do czynienia z ciągami znaków, które zawierają kombinację cyfr i liter rozpoczynających się cyfrą, nie uzyskasz oczekiwanych wyników. REGEXP zinterpretuje ciąg jako prawidłową liczbę, podczas gdy w rzeczywistości tak nie jest.
FALSE, zgodnie z oczekiwaniami, ponieważ wyrażenie regularne kończy się na, $co oznacza koniec ciągu, więc sprawdza tylko liczby, zgodnie z zamierzeniami autora.
Działa to dobrze w przypadku VARCHAR, w którym zaczyna się od liczby lub nie.
WHERE concat('',fieldname * 1) != fieldname
mogą mieć ograniczenia, gdy dojdziesz do większych liczb NNNNE + -
set @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;