Ich sehe, dass es in MySQL Cast()
und Convert()
Funktionen gibt, um Ganzzahlen aus Werten zu erstellen, aber gibt es eine Möglichkeit zu überprüfen, ob ein Wert eine Ganzzahl ist? So etwas wie is_int()
in PHP ist das, wonach ich suche.
Ich sehe, dass es in MySQL Cast()
und Convert()
Funktionen gibt, um Ganzzahlen aus Werten zu erstellen, aber gibt es eine Möglichkeit zu überprüfen, ob ein Wert eine Ganzzahl ist? So etwas wie is_int()
in PHP ist das, wonach ich suche.
Antworten:
Ich gehe davon aus, dass Sie einen Zeichenfolgenwert überprüfen möchten. Ein guter Weg ist der REGEXP-Operator, der die Zeichenfolge einem regulären Ausdruck zuordnet. Einfach machen
select field from table where field REGEXP '^-?[0-9]+$';
das ist ziemlich schnell. Wenn Ihr Feld numerisch ist, testen Sie einfach auf
ceil(field) = field
stattdessen.
Ordnen Sie es einem regulären Ausdruck zu.
Siehe http://forums.mysql.com/read.php?60,1907,38488#msg-38488 wie unten angegeben:
Betreff: IsNumeric () -Klausel in MySQL ??
Gepostet von: kevinclark ()
Datum: 08. August 2005, 13:01 Uhr
Genau. Hier ist eine Funktion, die ich für MySQL 5 erstellt habe:
CREATE FUNCTION IsNumeric (sIn varchar(1024)) RETURNS tinyint
RETURN sIn REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$';
Dies ermöglicht ein optionales Plus- / Minuszeichen am Anfang, einen optionalen Dezimalpunkt und die restlichen numerischen Ziffern.
Angenommen, wir haben eine Spalte mit einem alphanumerischen Feld mit Einträgen wie
a41q
1458
xwe8
1475
asde
9582
.
.
.
.
.
qe84
und Sie möchten den höchsten numerischen Wert aus dieser Datenbankspalte (in diesem Fall 9582), dann hilft Ihnen diese Abfrage
SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'
Hier ist die einfache Lösung dafür, vorausgesetzt, der Datentyp ist varchar
select * from calender where year > 0
Es wird true zurückgegeben, wenn das Jahr numerisch ist, andernfalls false
Dies funktioniert auch:
CAST( coulmn_value AS UNSIGNED ) // will return 0 if not numeric string.
beispielsweise
SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0
SELECT CAST('12a34' AS UNSIGNED)
, was zurückkommt 12
?
Um zu überprüfen, ob ein Wert in MySQL Int ist, können wir die folgende Abfrage verwenden. Diese Abfrage gibt die Zeilen mit Int-Werten an
SELECT col1 FROM table WHERE concat('',col * 1) = col;
Das Beste, was ich mir von einer Variablen vorstellen kann, ist ein int. Ist eine Kombination mit den Funktionen von MySQL CAST()
und LENGTH()
.
Diese Methode funktioniert für Zeichenfolgen, Ganzzahlen und Datentypen mit Doppel- / Gleitkommazahlen.
SELECT (LENGTH(CAST(<data> AS UNSIGNED))) = (LENGTH(<data>)) AS is_int
Siehe Demo http://sqlfiddle.com/#!9/ff40cd/44
Es schlägt fehl, wenn die Spalte einen einzelnen Zeichenwert hat. Wenn die Spalte den Wert 'A' hat, wird Cast ('A' als UNSIGNED) mit 0 und LENGTH (0) mit 1 bewertet. LENGTH (Cast ('A' als UNSIGNED)) = LENGTH (0) wird mit 0 bewertet 1 = 1 => 1
Der wahre Waqas Malik war total beschlagen, um diesen Fall zu testen. Der Patch ist.
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;
Ergebnisse
**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 |
siehe 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;
Dieses Refactoring behandelt alle oben genannten Fälle, aber selbst meine Anpassung behandelt nicht -1,0 oder '-1'. Wieder eine super coole Lösung.
Wie wäre es mit:
WHERE table.field = "0" or CAST(table.field as SIGNED) != 0
auf numerisch und korrolar testen:
WHERE table.field != "0" and CAST(table.field as SIGNED) = 0
Ich habe versucht, die oben aufgeführten regulären Ausdrücke zu verwenden, aber sie funktionieren nicht für Folgendes:
SELECT '12 INCHES' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
Das obige wird return 1
( TRUE
), was bedeutet, dass der Test der Zeichenfolge '12 INCHES 'gegen den obigen regulären Ausdruck zurückgegeben wirdTRUE
. Es sieht aus wie eine Zahl, die auf dem oben verwendeten regulären Ausdruck basiert. In diesem Fall interpretiert der reguläre Ausdruck die 12 als Zahl, da sie am Anfang der Zeichenfolge steht.
Im Folgenden wird der richtige Wert (dh 0
) zurückgegeben, da die Zeichenfolge mit Zeichen anstelle von Ziffern beginnt
SELECT 'TOP 10' REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$' FROM ...
Das obige wird 0
( FALSE
) zurückgeben, da der Anfang der Zeichenfolge Text und nicht numerisch ist.
Wenn Sie jedoch mit Zeichenfolgen arbeiten, deren Mischung aus Zahlen und Buchstaben mit einer Zahl beginnt, erhalten Sie nicht die gewünschten Ergebnisse. REGEXP interpretiert die Zeichenfolge als gültige Zahl, obwohl dies nicht der Fall ist.
FALSE
wie erwartet zurückgegeben, da der reguläre Ausdruck mit $
dem Ende der Zeichenfolge endet , sodass nur nach Zahlen gesucht wird, wie vom Autor beabsichtigt.
Dies funktioniert gut für VARCHAR, wo es mit einer Zahl beginnt oder nicht.
WHERE concat('',fieldname * 1) != fieldname
Möglicherweise gibt es Einschränkungen, wenn Sie zu den größeren NNNNE + - Nummern gelangen
set @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;