Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a value is a number in SQLite

Tags:

sql

sqlite

I have a column that contains numbers and other string values (like "?", "???", etc.)

Is it possible to add an "is number" condition to the where clause in SQLite? Something like:

select * from mytable where isnumber(mycolumn)
like image 963
Chin Avatar asked Sep 11 '15 17:09

Chin


People also ask

Is Numeric in SQLite?

Each column in an SQLite 3 database is assigned one of the following type affinities: TEXT. NUMERIC. INTEGER.

What is integer in SQLite?

INTEGER – any numeric value is stored as a signed integer value (It can hold both positive and negative integer values). The INTEGER values in SQLite are stored in either 1, 2, 3, 4, 6, or 8 bytes of storage depending on the value of the number.

What is the difference between real and numeric in SQLite?

The REAL storage class is used for numeric data with a decimal component. Floats would fit into this category. Other numbers without a decimal component would be assigned to the INTEGER storage class.

Can an integer be null in SQLite?

Based on the SQL standard, PRIMARY KEY should always imply NOT NULL . However, SQLite allows NULL values in the PRIMARY KEY column except that a column is INTEGER PRIMARY KEY column or the table is a WITHOUT ROWID table or the column is defined as a NOT NULL column. This is due to a bug in some early versions.


7 Answers

From the documentation,

The typeof(X) function returns a string that indicates the datatype of the expression X: "null", "integer", "real", "text", or "blob".

You can use where typeof(mycolumn) = "integer"

like image 130
Vamsi Prabhala Avatar answered Oct 03 '22 12:10

Vamsi Prabhala


You could try something like this also:

select * from mytable where printf("%d", field1) = field1;

In case your column is text and contains numeric and string, this might be somewhat helpful in extracting integer data.

Example:

CREATE TABLE mytable (field1 text);
insert into mytable values (1);
insert into mytable values ('a');

select * from mytable where printf("%d", field1) = field1;
field1
----------
1
like image 34
zedfoxus Avatar answered Oct 03 '22 10:10

zedfoxus


select * from mytable where abs(mycolumn) <> 0.0 or mycolumn = '0'

http://sqlfiddle.com/#!5/f1081/2

Based on this answer

like image 44
Richard Kelly Avatar answered Oct 03 '22 12:10

Richard Kelly


To test whether the column contains exclusively an integer with no other alphanumeric characters, use:

NOT myColumn GLOB '*[^0-9]*' AND myColumn LIKE '_%'

I.e., we test whether the column contains anything else than a digit and invert the result. Additionally we test whether it contains at least one character.

Note that GLOB '*[0-9]*' will find digits nested between other characters as well. The function typeof() will return 'text' for a column typed as TEXT, even if the text represents a number. As @rayzinnz mentioned, the abs() function is not reliable as well.

like image 44
Olivier Jacot-Descombes Avatar answered Oct 03 '22 11:10

Olivier Jacot-Descombes


SELECT * 
FROM mytable
WHERE columnNumeric  GLOB '*[0-9]*'
like image 32
Meysam Chegini Avatar answered Oct 03 '22 10:10

Meysam Chegini


As SQLite and MySQL follow the same syntax and loose datatypes.

The query below is also possible

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;

Note the <data> is BNF you would have the replace those values.

This answer is based on mine other answer

Running SQLite demo

like image 20
Raymond Nijland Avatar answered Oct 03 '22 10:10

Raymond Nijland


For integer strings, test whether the roundtrip CAST matches the original string:

SELECT * FROM mytable WHERE cast(cast(mycolumn AS INTEGER) AS TEXT) = mycolumn

For consistently-formatted real strings (for example, currency):

SELECT * FROM mytable WHERE printf("%.2f", cast(mycolumn AS REAL)) = mycolumn

Input values:

  • Can't have leading zeroes
  • Must format negatives as -number rather than (number).
like image 29
DenverCR Avatar answered Oct 03 '22 10:10

DenverCR