简体   繁体   中英

How to do a count of fields in SQL with wrong datatype

I am trying to import legacy data from another system into our system. The problem I am having is that the legacy data is dirty- very dirty! We have a field which should be an integer, but sometimes is a varchar, and the field is defined as a varchar...

In SQL Server, how can I do a select to show those records where the data is varchar instead if int?

Thanks

If you want to find rows 1 where a column contains any non-digit characters or is longer than 9 characters (either condition means that we cannot assume it would fit in an int , use something like:

SELECT * FROM Table WHERE LEN(ColumnName) > 9 or ColumnName LIKE '%[^0-9]%'

Not that there's a negative in the LIKE condition - we're trying to find a string that contains at least one non-digit character.

A more modern approach would be to use TRY_CAST or TRY_CONVERT . But note that a failed conversion returns NULL and NULL is perfectly valid for an int !

SELECT * FROM Table WHERE ColumnName is not null and try_cast(ColumnName as int) is null

ISNUMERIC isn't appropriate. It answers a question nobody has ever wanted to ask (IMO) - "Can this string be converted to any of the numeric data types (I don't care which ones and I don't want you to tell me which ones either)?"

ISNUMERIC('$,,,,,,,.') is 1 . That should tell you all you need to know about this function.


1 If you just want a count, as per the title of the question, then substitute COUNT(*) for * .

In SQL Server, how can I do a select to show those records where the data is varchar instead of int?

I would do it like

CREATE TABLE T
(
  Data VARCHAR(50)
);

INSERT INTO T VALUES
('102'),
(NULL),
('11Blah'),
('5'),
('Unknown'),
('1ThinkPad123'),
('-11');

SELECT Data -- Per the title COUNT(Data)
FROM
(
  SELECT Data, 
         cast('' as xml).value('sql:column("Data") cast as xs:int ?','int') Result
  FROM T --You can add WHERE Data IS NOT NULL to exclude NULLs
) TT
WHERE Result IS NULL;

Returns:

+----+--------------+
|    |     Data     |
+----+--------------+
|  1 | NULL         |
|  2 | 11Blah       |
|  3 | Unknown      |
|  4 | 1ThinkPad123 |
+----+--------------+

That if you can't use TRY_CAST() function, if you are working on 2012+ version, I'll recommend that you use TRY_CAST() function like

SELECT Data
FROM T
WHERE Data IS NOT NULL 
      AND 
      TRY_CAST(Data AS INT) IS NULL;

Demo


Finally, I would say do not use ISNUMERIC() function because of (from docs) ...

Note

ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM