Bagaimana cara memeriksa untuk melihat apakah suatu nilai adalah bilangan bulat di MySQL?

123

Saya melihat bahwa di dalam MySQL ada Cast()dan Convert()fungsi untuk membuat bilangan bulat dari nilai, tetapi apakah ada cara untuk memeriksa apakah suatu nilai adalah bilangan bulat? Sesuatu seperti is_int()di PHP adalah apa yang saya cari.

Craig Nakamoto
sumber
2
jadi sayangnya kita harus membuat fungsi is_int () di Mysql
Yuda Prawira

Jawaban:

214

Saya akan menganggap Anda ingin memeriksa nilai string. Salah satu cara yang bagus adalah operator REGEXP, mencocokkan string dengan ekspresi reguler. Lakukan saja

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

ini cukup cepat. Jika bidang Anda numerik, uji saja

ceil(field) = field

sebagai gantinya.

Gelisah
sumber
4
Tes 'ceil (field) = field' adalah ide yang bagus, tetapi seperti yang ditunjukkan @Jumpy, ini gagal pada data non-numerik: SELECT ceil ('four') = 'four'; -> 1
Matthew Cornell
3
@MatthewCornell, Dia berkata jika bidang Anda adalah numerik. Itu agar Anda dapat menguji apakah suatu angka adalah bilangan bulat. Itu tidak akan berfungsi pada string, itulah mengapa opsi pertama ada di sana.
Malfist
Jika data mungkin menyertakan spasi, ini akan gagal. Pertimbangkan untuk menguji trim (bidang), mungkin dengan argumen tambahan untuk menghapus baris baru.
Michael Grazebrook
datanya berupa numerik, dapat melakukan ini juga: pilih ((bidang% 1) = 0);
ThiamTeck
Terima kasih, tetapi untuk perbandingan numerik, saya pikir Anda tidak perlu (strcmp (ceil (field), field))
Alan Dixon
14

Cocokkan dengan ekspresi reguler.

cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488 seperti dikutip di bawah ini:

Re: Klausa IsNumeric () di MySQL ??
Dikirim oleh: kevinclark ()
Tanggal: 08 Agustus 2005 13:01


Saya setuju. Berikut adalah fungsi yang saya buat untuk 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]+)$';


Ini memungkinkan adanya tanda plus / minus opsional di awal, satu titik desimal opsional, dan digit numerik lainnya.

JBB
sumber
Terima kasih, solusi Anda juga menangani desimal
Ananda
12

Misalkan kita memiliki kolom dengan kolom alfanumerik yang memiliki entri seperti

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

dan Anda menginginkan nilai numerik tertinggi dari kolom db ini (dalam hal ini adalah 9582) maka kueri ini akan membantu Anda

SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'
Tarun Sood
sumber
1
'10000' lebih tinggi, tetapi kueri Anda masih akan mengembalikan '9582' .
Paul Spiegel
8

Berikut adalah solusi sederhana untuk itu dengan asumsi tipe datanya adalah varchar

select * from calender where year > 0

Ini akan mengembalikan nilai true jika tahun adalah numerik lain salah

Jayjitraj
sumber
29
Dalam varchar, ini juga akan mengembalikan nilai true jika karakter pertama adalah numerik.
TuK
Tidak menyadarinya. up-voting komentar Anda :)
Jayjitraj
8

Ini juga berfungsi:

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

sebagai contoh

SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0
Riad
sumber
11
bagaimana SELECT CAST('12a34' AS UNSIGNED), yang kembali 12?
Mike C
1
Ini berfungsi sempurna jika Anda perlu menguji item non-numerik, ini layak mendapatkan lebih banyak +1. Jawaban lain lebih sulit untuk membalikkan tes untuk menemukan item non-numerik.
DrCord
1
@DrCord ini tidak berfungsi untuk kasus yang dijelaskan Mike C, karenanya sangat tidak dapat diandalkan
jontro
4

Untuk memeriksa apakah suatu nilai adalah Int di Mysql, kita dapat menggunakan query berikut. Kueri ini akan memberikan baris dengan nilai Int

SELECT col1 FROM table WHERE concat('',col * 1) = col;
minhas23
sumber
Ini juga akan memilih angka non-integer (mis. '3.5' ).
Paul Spiegel
4

Yang terbaik yang bisa saya pikirkan tentang variabel adalah int. Apakah kombinasi dengan fungsi MySQL CAST()dan LENGTH().
Metode ini akan bekerja pada tipe data string, integer, doubles / floats.

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

lihat demo http://sqlfiddle.com/#!9/ff40cd/44

itu akan gagal jika kolom memiliki nilai karakter tunggal. jika kolom memiliki nilai 'A' maka Cast ('A' as UNSIGNED) akan bernilai 0 dan LENGTH (0) akan menjadi 1. jadi LENGTH (Cast ('A' as UNSIGNED)) = LENGTH (0) akan dievaluasi menjadi 1 = 1 => 1

Waqas Malik Sejati benar-benar salah menguji kasus itu. tambalannya.

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;

Hasil

**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      |

lihat demo

Raymond Nijland
sumber
itu akan gagal jika kolom memiliki nilai karakter tunggal. jika kolom memiliki nilai 'A' maka Cast ('A' as UNSIGNED) akan bernilai 0 dan LENGTH (0) akan menjadi 1. jadi LENGTH (Cast ('A' as UNSIGNED)) = LENGTH (0) akan dievaluasi menjadi 1 = 1 => 1
Waqas Malik
Terima kasih atas komentarnya bahwa kasus @WaqasMalik memang belum teruji bekerja dan menguji tambalan sekarang .. sesuatu sepertiSELECT "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
Ini adalah solusi yang keren. Saya pikir itu gagal untuk bilangan bulat negatif, apakah itu mengubah sesuatu yang substantif (dalam kasus tepi) untuk mengalihkan solusi Anda ke bilangan bulat yang ditandatangani? Saya telah menguji menggunakan biola Anda sebagai alasnya. 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;Refactoring ini menangani semua kasus di atas, tetapi bahkan penyesuaian saya tidak menangani -1.0 atau '-1.' Sekali lagi, solusi yang sangat keren.
spen.smith
3

Bagaimana dengan:

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

untuk menguji numerik dan korroler:

WHERE table.field != "0" and CAST(table.field as SIGNED) = 0
Tom Auger
sumber
1
CAST (table.field)! = 0 tidak akan berfungsi karena membutuhkan tipe untuk ditransmisikan.
Riad
Ini berfungsi sempurna jika Anda perlu menguji item non-numerik, ini layak mendapatkan lebih banyak +1. Jawaban lain lebih sulit untuk membalikkan tes untuk menemukan item non-numerik.
DrCord
Ini tidak berfungsi untuk angka seperti "0000", "0" (spasi) dan "7x" (yang dianggap sebagai angka).
Michael Grazebrook
@MichaelGrazebrook Saya kira Anda bisa melakukan regexp untuk dua kasus pertama. "7x" dianggap angka? "0x7" adalah angka, tapi 7x?
Tom Auger
1
@Tom Auger: Jawaban lain mencakup solusi tipe rege. Yang saya maksud dengan "7x dianggap angka" adalah pernyataan ini benar: pilih 7 = '7q'
Michael Grazebrook
1

Saya telah mencoba menggunakan ekspresi reguler yang tercantum di atas, tetapi tidak berfungsi untuk yang berikut:

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

Di atas akan mengembalikan 1( TRUE), yang berarti pengujian string '12 INCHES 'terhadap ekspresi reguler di atas, mengembalikanTRUE . Sepertinya angka yang didasarkan pada ekspresi reguler yang digunakan di atas. Dalam kasus ini, karena 12 berada di awal string, ekspresi reguler menafsirkannya sebagai angka.

Yang berikut ini akan mengembalikan nilai yang benar (yaitu 0) karena string dimulai dengan karakter, bukan angka

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

Di atas akan kembali 0(FALSE ) karena awal string adalah teks dan bukan numerik.

Namun, jika Anda berurusan dengan string yang memiliki campuran angka dan huruf yang dimulai dengan angka, Anda tidak akan mendapatkan hasil yang diinginkan. REGEXP akan menafsirkan string sebagai angka yang valid padahal sebenarnya tidak.

Bill Kelly
sumber
2
Ini salah Apakah Anda mengujinya? Ketika saya menjalankan contoh pertama Anda, itu mengembalikan FALSE, seperti yang diharapkan, karena regex berakhir dengan $yang berarti akhir dari string, jadi hanya memeriksa angka, seperti yang dimaksudkan oleh penulis.
spikyjt
1

Ini berfungsi dengan baik untuk VARCHAR yang dimulai dengan angka atau tidak ..

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

mungkin memiliki batasan ketika Anda mendapatkan nomor NNNNE + - yang lebih besar

PodTech.io
sumber
Ini sepertinya tidak berfungsi untuk string karakter tunggalset @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;
spen.smith
0

bagi saya satu-satunya hal yang berhasil adalah:

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

dari kevinclark semua barang-barang lain yang tidak berguna bagi saya jika terjadi 234jk456atau12 inches

Tim
sumber