Wie überprüfe ich, ob ein Wert in MySQL eine Ganzzahl ist?


122

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.


2
so leider müssen wir is_int () Funktion in Mysql
Yuda Prawira

Antworten:


213

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.


4
Der Test 'Ceil (Feld) = Feld' ist eine gute Idee, aber wie @Jumpy hervorhob, schlägt er bei nicht numerischen Daten fehl: SELECT Ceil ('Vier') = 'Vier'; -> 1
Matthew Cornell

2
@ MatthewCornell, sagte er, wenn Ihr Feld numerisch ist. Auf diese Weise können Sie testen, ob eine Zahl eine Ganzzahl ist. Es funktioniert nicht mit Strings, deshalb gibt es die erste Option.
Malfist

Wenn die Daten möglicherweise Leerzeichen enthalten, schlägt dies fehl. Erwägen Sie, Trim (Feld) zu testen, möglicherweise mit einem zusätzlichen Argument, um Zeilenumbrüche zu entfernen.
Michael Grazebrook

Wenn die Daten numerisch sind, können Sie dies auch tun: select ((Feld% 1) = 0);
ThiamTeck

Danke, aber für den numerischen Vergleich, ich denke, Sie brauchen nicht (strcmp (Ceil (Feld), Feld))
Alan Dixon

14

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.


Vielen Dank, Ihre Lösung kümmert sich auch um Dezimalstellen
Ananda

12

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]+$'

1
'10000' ist höher, aber Ihre Abfrage würde immer noch '9582' zurückgeben .
Paul Spiegel

8

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


29
In einem Varchar gibt dies auch true zurück, wenn das erste Zeichen numerisch ist.
Dienstag,

Hab das nicht bemerkt. Up-Voting Ihren Kommentar :)
Jayjitraj

8

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

11
was ist mit SELECT CAST('12a34' AS UNSIGNED), was zurückkommt 12?
Mike C

1
Dies funktioniert perfekt, wenn Sie auf nicht numerische Elemente testen müssen. Dies verdient mehr +1. Bei den anderen Antworten ist es schwieriger, den Test umzukehren, um die nicht numerischen Elemente zu finden.
DrCord

1
@ DrCord dies funktioniert nicht für den beschriebenen Fall Mike C, ist daher sehr unzuverlässig
jontro

4

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;

Dadurch werden auch nicht ganzzahlige Zahlen ausgewählt (z. B. '3.5' ).
Paul Spiegel

4

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


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
Waqas Malik

Vielen Dank für den Kommentar, dass der Fall in der Tat ungetestet war @WaqasMalik arbeitet und testet gerade einen Patch .. so etwas wieSELECT "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

Das ist so eine coole Lösung. Ich denke, es schlägt bei negativen Ganzzahlen fehl. Ändert es etwas Wesentliches (in Randfällen), um Ihre Lösung auf vorzeichenbehaftete Ganzzahlen umzustellen? Ich habe mit deiner Geige als Basis getestet. 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.
spen.smith

3

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

1
CAST (table.field)! = 0 funktioniert nicht, da zum Umwandeln ein Typ erforderlich ist.
Riad

Dies funktioniert perfekt, wenn Sie auf nicht numerische Elemente testen müssen. Dies verdient mehr +1. Bei den anderen Antworten ist es schwieriger, den Test umzukehren, um die nicht numerischen Elemente zu finden.
DrCord

Dies funktioniert nicht für Zahlen wie "0000", "0" (Leerzeichen) und "7x" (was als Zahl betrachtet wird).
Michael Grazebrook

@MichaelGrazebrook Ich nehme an, Sie könnten für die ersten beiden Fälle einen regulären Ausdruck machen. "7x" gilt als Zahl? "0x7" ist eine Zahl, aber 7x?
Tom Auger

1
@ Tom Auger: Eine weitere Antwort betraf die Lösungen vom Typ Regex. Was ich mit "7x ist eine Zahl" gemeint habe, ist, dass diese Aussage wahr ist: Wählen Sie 7 = '7q'
Michael Grazebrook

1

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.


2
Das ist falsch. Hast du es getestet? Wenn ich Ihr erstes Beispiel ausführe, wird es FALSEwie erwartet zurückgegeben, da der reguläre Ausdruck mit $dem Ende der Zeichenfolge endet , sodass nur nach Zahlen gesucht wird, wie vom Autor beabsichtigt.
Spikyjt

1

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


Dies scheint nicht für einzelne Zeichenfolgen zu funktionierenset @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;
spen.smith

0

Für mich funktioniert nur:

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

von kevinclark geben alle anderen nutzlose sachen für mich zurück, falls 234jk456oder12 inches

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.