Czy istnieje sposób na wykrycie, czy wartość jest liczbą w zapytaniu MySQL? Jak na przykład
SELECT *
FROM myTable
WHERE isANumber(col1) = true
Czy istnieje sposób na wykrycie, czy wartość jest liczbą w zapytaniu MySQL? Jak na przykład
SELECT *
FROM myTable
WHERE isANumber(col1) = true
Odpowiedzi:
To powinno działać w większości przypadków.
SELECT * FROM myTable WHERE concat('',col1 * 1) = col1
Nie działa w przypadku niestandardowych liczb, takich jak
1e4
1.2e5
123.
(końcowe dziesiętne)Możesz też użyć wyrażenia regularnego ... wyglądałoby to tak:
SELECT * FROM myTable WHERE col1 REGEXP '^[0-9]+$';
WHERE col1 NOT REGEXP...
oraz w przypadku, gdy możesz mieć przecinek dziesiętny, użyj wyrażenia regularnego:^[0-9\.]+$
Jeśli Twoje dane to „test”, „test0”, „test1111”, „111test”, „111”
Aby wybrać wszystkie rekordy, w których dane są prostą liczbą int:
SELECT *
FROM myTable
WHERE col1 REGEXP '^[0-9]+$';
Wynik: `` 111 ''
(W wyrażeniu regularnym ^ oznacza początek, a $ oznacza koniec)
Aby wybrać wszystkie rekordy, w których istnieje liczba całkowita lub dziesiętna:
SELECT *
FROM myTable
WHERE col1 REGEXP '^[0-9]+\\.?[0-9]*$'; - for 123.12
Wynik: „111” (tak samo jak w ostatnim przykładzie)
Na koniec, aby wybrać wszystkie rekordy, w których istnieje numer, użyj tego:
SELECT *
FROM myTable
WHERE col1 REGEXP '[0-9]+';
Wynik: „test0” i „test1111” oraz „111test” i „111”
REGEXP '^[+\-]?[0-9]+\\.?[0-9]*$'
SELECT * FROM myTable
WHERE col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$'
Dopasuje również liczby dziesiętne ze znakiem (np. -1,2, +0,2, 6., 2e9, 1,2e-10 ).
Test:
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;
Wynik:
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
Zwraca wiersze liczbowe
Znalazłem rozwiązanie z następującym zapytaniem i działa dla mnie:
SELECT * FROM myTable WHERE col1 > 0;
To zapytanie zwraca wiersze mające tylko kolumnę z liczbą większą niż zero col1
Zwraca wiersze nienumeryczne
jeśli chcesz sprawdzić kolumnę, a nie numeryczną, spróbuj tego z trick ( !col1 > 0
):
SELECT * FROM myTable WHERE !col1 > 0;
SELECT * FROM myTable WHERE col1 = 123;
zapytanie zwróci wiersze, nawet wartość col to123abc
użyj UDF (funkcja zdefiniowana przez użytkownika).
CREATE FUNCTION isnumber(inputValue VARCHAR(50))
RETURNS INT
BEGIN
IF (inputValue REGEXP ('^[0-9]+$'))
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
Wtedy, gdy zapytasz
select isnumber('383XXXX')
- zwroty 0
select isnumber('38333434')
- zwroty 1
wybierz isnumber (mycol) mycol1, col2, colx z tabeli x; - zwróci 1 i 0 dla kolumny mycol1
- możesz rozszerzyć funkcję o ułamki dziesiętne, notację naukową itp.
Zaletą korzystania z funkcji UDF jest to, że można jej używać po lewej lub prawej stronie porównania „klauzula where”. to znacznie upraszcza SQL przed wysłaniem do bazy danych:
SELECT * from tablex where isnumber(columnX) = isnumber('UnkownUserInput');
mam nadzieję że to pomoże.
Inną alternatywą, która wydaje się szybsza niż REGEXP na moim komputerze, jest
SELECT * FROM myTable WHERE col1*0 != col1;
Spowoduje to zaznaczenie wszystkich wierszy, w których col1 zaczyna się od wartości liczbowej.
AND col1<>0
aby obsłużyć ten wyjątek.
'1a'
. BTW: to odpowiednik WHERE col1 <> 0
- rextester.com/DJIS1493
Wciąż brakuje tej prostej wersji:
SELECT * FROM myTable WHERE `col1` + 0 = `col1`
(dodawanie powinno być szybsze jako mnożenie)
Lub najwolniejsza wersja do dalszej gry:
SELECT *,
CASE WHEN `col1` + 0 = `col1` THEN 1 ELSE 0 END AS `IS_NUMERIC`
FROM `myTable`
HAVING `IS_NUMERIC` = 1
'a' + 0 = 'a'
jest PRAWDA
Polecam: jeśli twoje wyszukiwanie jest proste, możesz użyć `
column*1 = column
`operator ciekawy :) działa i szybciej niż na polach varchar / char
SELECT * FROM myTable WHERE kolumna * 1 = kolumna;
ABC*1 => 0 (NOT EQU **ABC**)
AB15*A => 15 (NOT EQU **AB15**)
15AB => 15 (NOT EQU **15AB**)
15 => 15 (EQUALS TRUE **15**)
select 'aaa123' >= 0
i select '123aaa' >= 0
return true?
SELECT * FROM myTable WHERE sign (col1)!=0
oczywiście znak (0) wynosi zero, ale wtedy możesz ograniczyć zapytanie do ...
SELECT * FROM myTable WHERE sign (col1)!=0 or col1=0
AKTUALIZACJA: Nie jest to w 100% wiarygodne, ponieważ „1abc” zwróciłoby znak 1, ale „ab1c” zwróciłoby zero… więc może to działać tylko w przypadku tekstu, który nie zaczyna się od cyfr.
Spróbuj podzielić / 1
select if(value/1>0 or value=0,'its a number', 'its not a number') from table