MySQL'de değerin sayı olup olmadığını tespit edin


159

Bir değerin MySQL sorgusundaki bir sayı olup olmadığını tespit etmenin bir yolu var mı? Gibi

SELECT * 
FROM myTable 
WHERE isANumber(col1) = true

1 * col = col stratejisini test ettim, ancak bir şekilde sorgu PHP (çağrılmadığında true döndüren) çağrıldığında başarısız olur. Ancak phpMyAdmin'de kesmek çalışır. Bu, testimin beklendiği gibi davrandığı, başvurumu satın almadığı anlamına geliyor.
Jahaziel

Yanıtlar:


251

Bu çoğu durumda işe yarar.

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

Standart olmayan sayılar için çalışmaz

  • 1e4
  • 1.2e5
  • 123. (sondaki ondalık)

Teşekkür ederim. Ne yazık ki 123'ün bir sayı olduğunu fark etmeliyim, ama 123X değil.
Urbycoz

1
@ Richard- Az önce verdiğin istisnaları okudum. "E" karakterini kastettiğini sanıyordum. Ne demek istediğini şimdi anlıyorum.
Urbycoz

Önde gelen sıfırlar, becerikli bir sql geliştiricisi için bir sorun değildir - trim (
col1'den

Eski bir yazı olduğunu biliyorum ama benim sorgu bu yöntemi kullanın. Ama bir sorunum var, "2-Power" ı "2" olarak algılıyor, bunu yapması gerekmediğinden belaya neden oluyor. Herhangi bir fikir ?
GRosay

1
Sondaki ve baştaki sıfırlar için (örn. 023.12000): concat ('', col1 * 1) = '0' VEYA concat ('', col1 * 1) = IF (LOCATE ('.', Col1), TRIM (BOTH ') 0 'FROM col1), TRIM (col1' LİDER '0' FROM 1));
François Breton

299

Normal İfadeyi de kullanabilirsiniz ...

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

Referans: http://dev.mysql.com/doc/refman/5.1/en/regexp.html


70
SEÇİMİ * KONTROL NEREDEN col1 REGEXP '^ [0-9] + $';
Dmitriy Kozmenko

7
Kabul edilen cevap gerçekten akıllıdır, ancak bu cevap daha doğrudandır ve bence kabul edilen çözüm olmalıdır.
pedromanoel

21
"Eşleşmiyor" durumunda: WHERE col1 NOT REGEXP...ve ondalık basamağınız olabileceği durumda regex kullanın:^[0-9\.]+$
Robbie Averill

2
Ayrıca bilimsel gösterim için çalışmaz, sadece ints için çalışır
David Wilkins

1
Regex migth hiç kullanmayan insanlar için okumak zor, ama onunla gerçekten harika ve kısa şeyler yapabilirsiniz
Olli

56

Verileriniz 'test', 'test0', 'test1111', '111test', '111'

Verilerin basit bir int olduğu tüm kayıtları seçmek için:

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

Sonuç: '111'

(Normal ifadede, ^ başlangıç ​​ve $ bitiş anlamına gelir)

Bir tamsayı veya ondalık sayının bulunduğu tüm kayıtları seçmek için:

SELECT * 
FROM myTable 
WHERE col1 REGEXP '^[0-9]+\\.?[0-9]*$'; - for 123.12

Sonuç: '111' (son örnekle aynı)

Son olarak, numaranın bulunduğu tüm kayıtları seçmek için şunu kullanın:

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

Sonuç: 'test0' ve 'test1111' ve '111test' ve '111'


Bu yaklaşımı daha çok seviyorum çünkü birleştirme hilesinden daha net ve daha az "hackish". Teşekkürler!
brokethebuildagain

8
Negatif değerler için çalışmıyor. Önerilen normal ifadeyi aşağıdaki gibi değiştiririm:REGEXP '^[+\-]?[0-9]+\\.?[0-9]*$'
Nicolas

"+" Sembolünün gerekli olmadığını söyleyebilirim, sadece bir "-?" Kullanabilirsiniz, ancak kullanmak istiyorsanız, kaçmalısınız (ve "-" sembolünden kaçmak gerekmez) .
T. Corner

13
SELECT * FROM myTable
WHERE col1 REGEXP '^[+-]?[0-9]*([0-9]\\.|[0-9]|\\.[0-9])[0-9]*(e[+-]?[0-9]+)?$'

İmzalı ondalıklarla da eşleşir ( -1.2, +0.2, 6., 2e9, 1.2e-10 gibi ).

Ölçek:

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;

Sonuç:

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

gösteri


3
Mükemmel! Sadece tüm üsleri kapsayan cevap. Kabul edilen cevap olmalı.
Dom

10

Sayısal satırları döndürür

Aşağıdaki sorgu ile çözüm buldum ve benim için çalışıyor:

SELECT * FROM myTable WHERE col1 > 0;

Bu sorgu yalnızca sıfırdan büyük sütun içeren satırları döndürür. col1

Sayısal olmayan satırları döndürür

sayısal olmayan sütunu kontrol etmek istiyorsanız bunu trick ( !col1 > 0) ile deneyin :

SELECT * FROM myTable WHERE !col1 > 0;

Bu işe yaramaz, "123abc" ile başlayan bir dizeniz varsa, sayısal olmayan deyimde değil, sayısal satırlar deyiminizde döndürülür.
JStephen

@JStephen Haklısın! Çünkü SELECT * FROM myTable WHERE col1 = 123;sorgu col değerini bile satır döndürecek123abc
Bora

9

Bu cevap Dmitry'ye benzer, ancak pozitif ve negatif sayıların yanı sıra ondalık sayılara da izin verecektir.

select * from table where col1 REGEXP '^[[:digit:]]+$'

8

bir UDF kullanın (kullanıcı tanımlı fonksiyon).

CREATE FUNCTION isnumber(inputValue VARCHAR(50))
  RETURNS INT
  BEGIN
    IF (inputValue REGEXP ('^[0-9]+$'))
    THEN
      RETURN 1;
    ELSE
      RETURN 0;
    END IF;
  END;

Sonra sorgulamak

select isnumber('383XXXX') 

--0 döndürür

select isnumber('38333434') 

--1 döndürür

tablex'ten isnumber (mycol) mycol1, col2, colx'i seçin; - mycol1 sütunu için 1s ve 0s döndürür

- ondalık sayı, bilimsel gösterim vb.

Bir UDF kullanmanın avantajı, "nerede yan tümcesi" karşılaştırmanızın sol veya sağ tarafında kullanabilmenizdir. bu, veritabanına gönderilmeden önce SQL'inizi büyük ölçüde basitleştirir:

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

Bu yardımcı olur umarım.


5

Bilgisayarımdaki REGEXP'den daha hızlı görünen başka bir alternatif

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

Bu, col1 öğesinin sayısal bir değerle başladığı tüm satırları seçer.


2
Değer sıfırsa ne olur?
Urbycoz

1
Sanırım AND col1<>0bu istisnayı ele almak için ekleyebilirsiniz .
Urbycoz

Sıfır değerleri için çalışmadığı, ancak 004 gibi yastıklı sayılar için mükemmel çalıştığı doğrudur. Kabul edilen yanıt, yastıklı sayılar için çalışmaz
Abbas

Bence bu sayıları kontrol etmenin en iyi yolu. Sadece sıfırı kontrol etmek için bir OR ifadesi eklememiz gerekiyor, çünkü SELT * FROM myTable NEREDE col1 * 0! = Col1 VEYA col1 = '0';
Binu Raman

İçin yanlış bir pozitif alıyorum '1a'. BTW: eşdeğerdir WHERE col1 <> 0- rextester.com/DJIS1493
Paul Spiegel

4

Bu basit sürümü hâlâ eksik:

SELECT * FROM myTable WHERE `col1` + 0 = `col1`

(toplama çarpma işlemi kadar hızlı olmalıdır)

Ya da daha fazla oynamak için en yavaş sürüm:

SELECT *, 
CASE WHEN `col1` + 0 = `col1` THEN 1 ELSE 0 END AS `IS_NUMERIC` 
FROM `myTable`
HAVING `IS_NUMERIC` = 1

3
Yanlış anlamadığım sürece, MySQL herhangi bir dizeyi 0'a dönüştürür, böylece bu dize ve sayılar arasında ayrım yapmaz, her ikisi de aynı döndürür.
Ivan McA

3
'a' + 0 = 'a'DOĞRU
Paul Spiegel

3

Öneririm: aramanız basitse,

column*1 = column

`operatör ilginç :) çalışma ve alanlardan daha hızlı varchar / char

SEÇ * myTable NEREDEN sütun * 1 = sütun;

ABC*1 => 0 (NOT EQU **ABC**)
AB15*A => 15 (NOT EQU **AB15**)
15AB => 15 (NOT EQU **15AB**)
15 => 15 (EQUALS TRUE **15**)

1
MySQL'de hem select 'aaa123' >= 0ve select '123aaa' >= 0dönüşün doğru olduğunu biliyor musunuz ?
Grzegorz Smulko

1
SELECT * FROM myTable WHERE sign (col1)!=0

ofcourse sign (0) sıfır, ancak daha sonra sorgunuzu kısıtlayabilirsiniz ...

SELECT * FROM myTable WHERE sign (col1)!=0 or col1=0

GÜNCELLEME: Bu% 100 güvenilir değildir, çünkü "1abc" 1 işareti döndürür, ancak "ab1c" sıfır döndürür ... bu nedenle bu yalnızca sayılarla başlamayan metinler için kullanılabilir.


0

kullanarak yapabilirsin CAST

  SELECT * from tbl where col1 = concat(cast(col1 as decimal), "")


-1

Bölmeyi deneyin / 1

select if(value/1>0 or value=0,'its a number', 'its not a number') from table
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.