Tôi thấy rằng trong MySQL có Cast()
và các Convert()
hàm tạo số nguyên từ các giá trị, nhưng có cách nào để kiểm tra xem một giá trị có phải là số nguyên không? Một cái gì đó giống như is_int()
trong PHP là những gì tôi đang tìm kiếm.
Tôi thấy rằng trong MySQL có Cast()
và các Convert()
hàm tạo số nguyên từ các giá trị, nhưng có cách nào để kiểm tra xem một giá trị có phải là số nguyên không? Một cái gì đó giống như is_int()
trong PHP là những gì tôi đang tìm kiếm.
Câu trả lời:
Tôi giả sử bạn muốn kiểm tra một giá trị chuỗi. Một cách hay là toán tử REGEXP, khớp chuỗi với một biểu thức chính quy. Đơn giản là làm
select field from table where field REGEXP '^-?[0-9]+$';
điều này khá nhanh. Nếu trường của bạn là số, chỉ cần kiểm tra
ceil(field) = field
thay thế.
So khớp nó với một biểu thức chính quy.
cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488 như được trích dẫn bên dưới:
Re: Mệnh đề IsNumeric () trong MySQL ??
Đăng bởi: kevinclark ()
Ngày: 08 tháng 8 năm 2005 01:01 PM
Tôi đồng ý. Đây là một hàm tôi đã tạo cho 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]+)$';
Điều này cho phép một dấu cộng / trừ tùy chọn ở đầu, một dấu thập phân tùy chọn và các chữ số số còn lại.
Giả sử chúng ta có cột với trường chữ và số có các mục nhập như
a41q
1458
xwe8
1475
asde
9582
.
.
.
.
.
qe84
và bạn muốn giá trị số cao nhất từ cột db này (trong trường hợp này là 9582) thì truy vấn này sẽ giúp bạn
SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'
Điều này cũng hoạt động:
CAST( coulmn_value AS UNSIGNED ) // will return 0 if not numeric string.
ví dụ
SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0
SELECT CAST('12a34' AS UNSIGNED)
, những gì trả lại 12
?
Để kiểm tra xem một giá trị có phải là Int trong Mysql hay không, chúng ta có thể sử dụng truy vấn sau. Truy vấn này sẽ cung cấp cho các hàng có giá trị Int
SELECT col1 FROM table WHERE concat('',col * 1) = col;
Điều tốt nhất tôi có thể nghĩ về một biến là một int Là sự kết hợp với các chức năng của MySQL CAST()
và LENGTH()
.
Phương thức này sẽ hoạt động trên các kiểu dữ liệu chuỗi, số nguyên, double / float.
SELECT (LENGTH(CAST(<data> AS UNSIGNED))) = (LENGTH(<data>)) AS is_int
xem bản demo http://sqlfiddle.com/#!9/ff40cd/44
nó sẽ không thành công nếu cột có một giá trị ký tự duy nhất. nếu cột có giá trị 'A' thì Cast ('A' là UNSIGNED) sẽ đánh giá là 0 và LENGTH (0) sẽ là 1. vì vậy LENGTH (Cast ('A' as UNSIGNED)) = LENGTH (0) sẽ đánh giá là 1 = 1 => 1
True Waqas Malik hoàn toàn mù mờ để kiểm tra trường hợp đó. bản vá là.
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;
Các kết quả
**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 |
xem 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;
Việc tái cấu trúc này xử lý tất cả các trường hợp trên, nhưng ngay cả điều chỉnh của tôi cũng không xử lý -1.0 hoặc '-1.' Một lần nữa, một giải pháp siêu hay.
Thế còn:
WHERE table.field = "0" or CAST(table.field as SIGNED) != 0
để kiểm tra số và corrolary:
WHERE table.field != "0" and CAST(table.field as SIGNED) = 0
Tôi đã thử sử dụng các biểu thức chính quy được liệt kê ở trên, nhưng chúng không hoạt động cho những điều sau:
SELECT '12 INCHES' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
Ở trên sẽ trả về 1
( TRUE
), nghĩa là kiểm tra chuỗi '12 INCHES 'so với biểu thức chính quy ở trên, trả về TRUE
. Nó trông giống như một số dựa trên biểu thức chính quy được sử dụng ở trên. Trong trường hợp này, bởi vì số 12 ở đầu chuỗi, biểu thức chính quy hiểu nó như một số.
Phần sau sẽ trả về giá trị bên phải (tức là 0
) vì chuỗi bắt đầu bằng ký tự thay vì chữ số
SELECT 'TOP 10' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
Ở trên sẽ trả về 0
( FALSE
) vì phần đầu của chuỗi là văn bản chứ không phải số.
Tuy nhiên, nếu bạn đang xử lý các chuỗi có sự kết hợp của số và chữ cái bắt đầu bằng một số, bạn sẽ không nhận được kết quả như mong muốn. REGEXP sẽ diễn giải chuỗi là một số hợp lệ trong khi thực tế không phải vậy.
FALSE
, như mong đợi, bởi vì regex kết thúc bằng $
nghĩa là cuối chuỗi, vì vậy nó chỉ kiểm tra các số, như dự định của tác giả.
Điều này hoạt động tốt cho VARCHAR khi nó bắt đầu bằng một số hoặc không ..
WHERE concat('',fieldname * 1) != fieldname
có thể có những hạn chế khi bạn đến số NNNNE + - lớn hơn
set @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;