Find All Non-Numeric Values in a Column in SQL

If you ever encounter a character column that should be numeric, there’s always a possibility that it contains non-numeric data that you don’t know about.

For example, someone might have set up a Price column as a varchar column that should have been a numeric column, and now you need to clean up after them. You might start by identifying all non-numeric data so that you can work out what to do with it before converting the column to a numeric type.

In SQL, you can run a query to return non-numeric data from the column. The query you use will largely depend on your DBMS.

SQL Server

SQL Server has an ISNUMERIC() function that returns 1 for numeric values and 0 for non-numeric values.

Here’s an example of using this function to return just the non-numeric values from a column:

SELECT c1
FROM t1
WHERE ISNUMERIC(c1) <> 1;

Here, c1 is a varchar column (that may or may not contain numeric data) and t1 is the table.

In this case we used ISNUMERIC() in a WHERE clause to narrow the query results to just those where the result of ISNUMERIC(c1) is not 1.

Another way to do it would be to use = 0 instead of <> 1.

Oracle

In Oracle, we can negate the REGEXP_LIKE() function with a regular expression pattern:

SELECT c1
FROM t1 
WHERE NOT REGEXP_LIKE(c1, '^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$');

The regex pattern matches floating point numbers, and so we negated it with NOT.

Matching non-integers can be done with a less complex pattern:

SELECT c1
FROM t1 
WHERE NOT REGEXP_LIKE(c1, '^[0-9]+$');

MySQL

In MySQL, we can negate the REGEXP operator:

SELECT c1
FROM t1 
WHERE c1 NOT REGEXP '^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$';

For non-integers, we can use the same pattern that we used in the Oracle example for matching non-integers:

SELECT c1
FROM t1 
WHERE c1 NOT REGEXP '^[0-9]+$';

MariaDB

In MariaDB, we can negate its implementation of the REGEXP operator:

SELECT c1
FROM t1 
WHERE c1 NOT REGEXP '^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$';

And for non-integers:

SELECT c1
FROM t1 
WHERE c1 NOT REGEXP '^[0-9]+$';

PostgreSQL

Here’s the Postgres version:

SELECT c1
FROM t1 
WHERE c1 !~ '^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$';

And for non-integers:

SELECT c1
FROM t1 
WHERE c1 !~ '^[0-9]+$';

SQLite

In SQLite, we have a couple of options. We can use the typeof() function to filter the results to just numeric types (real and integer), then negate that:

SELECT c1
FROM t1
WHERE typeof(c1) <> 'integer'
AND typeof(c1) <> 'real';

In this case we can remove the AND operator to limit it to just non-integers.

Alternatively, we could use typeof() to check for only types of null, text, or blob.

If we prefer to use a regex pattern, we can apply that with the REGEXP function:

SELECT c1
FROM t1 
WHERE c1 NOT REGEXP '^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$';

For non-integers, we can apply the same pattern as with the previous examples for non-integers.