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.