MySQLで値が整数かどうかを確認するにはどうすればよいですか?


122

私は、MySQLの中にあることを確認Cast()し、Convert()値から整数を作成するための機能が、値が整数であるかどうかを確認する方法はありますか?is_int()PHPのようなものが私が探しているものです。


2
悲しいことに、Mysqlでis_int()関数を作成する必要があります
Yuda Prawira

回答:


213

文字列の値を確認したいとします。良い方法の1つはREGEXP演算子で、文字列を正規表現と照合します。単に行う

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

これはかなり高速です。フィールドが数値の場合は、テストしてください

ceil(field) = field

代わりに。


4
'ceil(field)= field'テストは良いアイデアですが、@ Jumpyが指摘したように、数値以外のデータでは失敗します。SELECT ceil( 'four')= 'four'; -> 1
マシューコーネル

2
@MatthewCornell、彼はあなたのフィールドが数値かどうかを言った。これは、数値が整数かどうかをテストできるようにするためです。文字列では機能しません。そのため、最初のオプションがあります。
Malfist 2013年

データに空白が含まれている可能性がある場合、これは失敗します。改行を削除する追加の引数を使用して、trim(field)をテストすることを検討してください。
Michael Grazebrook 2015年

データは数値であり、これも行う可能性があります。select((field%1)= 0);
ThiamTeck 2016年

ありがとうございますが、数値比較の場合は必要ないようです(strcmp(ceil(field)、field))
Alan Dixon

14

正規表現と照合します。

cf http://forums.mysql.com/read.php?60,1907,38488#msg-38488 as quoted under

Re:MySQLのIsNumeric()句??
投稿者:kevinclark()
日付:2005年8月8日01:01 PM


同意する。これは、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]+)$';


これにより、最初にオプションのプラス/マイナス記号、1つのオプションの小数点、および残りの数字を使用できます。


おかげで、あなたのソリューションは小数も処理します
アナンダ

12

次のようなエントリを持つ英数字フィールドを持つ列があるとします。

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

このdb列から最高の数値が必要な場合(この場合は9582です)、このクエリが役立ちます

SELECT Max(column_name) from table_name where column_name REGEXP '^[0-9]+$'

1
'10000'の方が高いですが、クエリは'9582'を返します。
ポールシュピーゲル

8

これは、データ型がvarcharであると仮定した場合の簡単な解決策です

select * from calender where year > 0

年が数値の場合はtrueを返し、それ以外の場合はfalseを返します


29
varcharでは、最初の文字が数値の場合もtrueを返します。
TuK

気づかなかった。コメントを投票する:)
Jayjitraj '13

8

これも機能します:

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

例えば

SELECT CAST('a123' AS UNSIGNED) // returns 0
SELECT CAST('123' AS UNSIGNED) // returns 123 i.e. > 0

11
どの程度SELECT CAST('12a34' AS UNSIGNED)、どのリターン12
Mike C

1
数値以外の項目をテストする必要がある場合、これは完璧に機能します。これは、+ 1を増やすに値します。他の答えは、数値以外の項目を見つけるためにテストを逆にするのが困難です。
DrCord 2014

1
@DrCordこれは、マイクCが説明したケースでは機能しないため、非常に信頼できません
jontro

4

Mysqlで値がIntかどうかを確認するには、次のクエリを使用できます。このクエリは、Int値を持つ行を提供します

SELECT col1 FROM table WHERE concat('',col * 1) = col;

これにより、整数以外の数値も選択されます(例:'3.5')。
ポールシュピーゲル

4

私が変数と考えることができる最高のものはintですMySQLの関数CAST()との組み合わせLENGTH()です。
このメソッドは、文字列、整数、倍精度浮動小数点データ型で機能します。

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

デモを見るhttp://sqlfiddle.com/#!9/ff40cd/44

列に単一の文字値がある場合は失敗します。列の値が 'A'の場合、Cast( 'A' as UNSIGNED)は0に評価され、LENGTH(0)は1になるため、LENGTH(Cast( 'A' as UNSIGNED))= LENGTH(0)は次のように評価されます1 = 1 => 1

True Waqas Malikはそのケースをテストするために完全にfogoteしました。パッチです。

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;

結果

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

デモを見る


列に単一の文字値がある場合は失敗します。列の値が 'A'の場合、Cast( 'A' as UNSIGNED)は0に評価され、LENGTH(0)は1になるため、LENGTH(Cast( 'A' as UNSIGNED))= LENGTH(0)は次のように評価されます1 = 1 => 1
Waqas Malik

ケースが実際にテストされていない@WaqasMalikが...今のようなものパッチを作業してテストしていたことをコメントしてくれてありがとう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;
レイモンドNijland

これはそのようなクールなソリューションです。負の整数では失敗すると思いますが、ソリューションを符号付き整数に切り替えるために(エッジケースで)実質的な変更はありますか?私はあなたのフィドルをベースにしてテストしてきました。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;このリファクタリングは上記のすべてのケースを処理しますが、私の調整でさえ-1.0または '-1'を処理しません。再び、超クールなソリューション。
spen.smith

3

何について:

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

数値と冠詞をテストするには:

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

1
CAST(table.field)!= 0は、キャストする型が必要なため機能しません。
Riad

数値以外の項目をテストする必要がある場合、これは完璧に機能します。これは、+ 1を増やすに値します。他の答えは、数値以外の項目を見つけるためにテストを逆にするのが困難です。
DrCord 2014

これは、「0000」、「0」(スペース)、「7x」(数値と見なされます)などの数値では機能しません。
Michael Grazebrook 2015年

@MichaelGrazebrook最初の2つのケースで正規表現を実行できると思います。「7x」は数字と見なされますか?「0x7」は数字ですが、7x?
トム・オージェ

1
@Tom Auger:もう1つの回答は、正規表現タイプのソリューションをカバーしています。「7xは数値と見なされる」とは、次のステートメントが真であることを意味します
。select7

1

上記の正規表現を使用してみましたが、次の場合は機能しません。

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

上記は1TRUE)を返しますTRUE。つまり、上記の正規表現に対する文字列'12 INCHES 'のテストはを返します。これは、上記で使用した正規表現に基づく数字のように見えます。この場合、12は文字列の先頭にあるため、正規表現は12を数値として解釈します。

以下は0、文字列が数字ではなく文字で始まるため、正しい値(つまり)を返します

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

文字列の先頭は数値ではなくテキストであるため、上記は0FALSE)を返します。

ただし、数字と数字で始まる文字が混在する文字列を処理している場合は、期待どおりの結果が得られません。REGEXPは、実際にはそうではない場合でも、文字列を有効な数値として解釈します。


2
これは誤りです。テストしましたか?最初の例を実行するFALSEと、期待どおりが返されます。これは、正規表現$の末尾が文字列の終わりであるため、作成者が意図したとおりに数値のみをチェックしているためです。
spikyjt 14

1

これは、数値で始まるかどうかにかかわらず、VARCHARでうまく機能します。

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

NNNNE +-の数値が大きくなると制限がある場合があります


これは単一の文字列では機能しないようですset @val = '5'; SELECT @val, concat('', @val * 1) != @val is_int;
spen.smith

0

私にとって機能するのは、次の点のみです。

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

kevinclarkからの場合、私のために他のすべてのリターン無用のもの234jk45612 inches

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.