tags:

views:

46

answers:

4

I have a table that has a column that has the cost of a product, but some (very few) rows have text mixed in the column.

Would it be possible to create a new column, of a decimal type, and populate it with the other column and just ignore the rows with the 'bad' data in it?

I know I can do this via code, but was hoping I could do it with a sql query some how?

+4  A: 

You can use a case to cast only the integer columns. This would return NULL for non-numeric columns:

select 
    case when isnumeric(col1) = 1 then cast(col1 as int) end
from YourTable

Or you can just ignore the non-numeric columns:

select *
from YourTable
where isnumeric(col1) = 1
Andomar
I am getting: Error converting data type nvarchar to numeric.I did: when isnumeric(pricetext) = 1 then costPrice / cast(priceText as decimal)
Blankman
+1, ISNUMERIC() is the way to go. @Blankman, this is valid working code, I tested it on my system. What data type is `costPrice`? show your query and list column datatypes. my test case: `declare @YourTable table (RowValue varchar(10), x int);INSERT INTO @YourTable VALUES ('ZZZ',2);INSERT INTO @YourTable VALUES ('123',2);INSERT INTO @YourTable VALUES ('1A23',2);INSERT INTO @YourTable VALUES ('AAA',2);select case when isnumeric(RowValue) = 1 then cast(RowValue as int)/x end from @YourTable`
KM
strange, it works with the WHERE clause! thanks.
Blankman
A: 

How does this sound? I use it all the time. Simple & quick.

NewColumn: iif(
               isnumeric([OldColumn]),
               cdbl([OldColumn])
           )
PowerUser
SQL Server does not support `iif`
Andomar
Ah, yes. This would only work for MS Access then.
PowerUser
A: 

As another example, you could use the PATINDEX, to check for Characters. If the value returned is greater that 0, then a character is present. The number will also tell you where the first character was detected in the column.

e.g.

DECLARE @String AS VARCHAR(100)
SET @String = '1234456'

SELECT PATINDEX('%[A-Z]%',@String)

Will return 0, which is ok

DECLARE @String AS VARCHAR(100)
SET @String = '1234frg456'

SELECT PATINDEX('%[A-Z]%',@String)

Will return 5, which is the position of the first character found.

I expect you can apply this in the WHERE clause, in part of an UPDATE for your new column.

e.g Apolgies if syntax is wrong

UPDATE <TABLE>
SET NewColumn = OldColumn
WHERE PATINDEX('%[A-Z]%', OldColumn) = 0
kevchadders
+2  A: 

Yes what you are asking is possible to do.

Step 1: Add a new column

Add a decimal (9, 2) column (PriceOfItem) to your table (ItemPrices)

Step 2: Run this query (change object names as required)

Update ItemPrices
Set PriceOfItem = Convert (Decimal (9, 2), PriceText)
Where 1=1
AND IsNumeric (PriceText) = 1
Raj More
I'm interested to know why you have "1=1" in the WHERE clause? It equates to true and would be optimised out.
Tony
@Tony: It is purely for ease of coding. If I have multiple `AND` clauses, and I have to comment them out or indent them, it is real easy. Try commenting out various parts of a `WHERE` with 3 `AND` parts to it, with and without a '1=1` and you will see what I mean.
Raj More
@Raj More: Thanks for the explanation. I see what you mean, it makes it easy to remove parts of the clause.
Tony