Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
pikthulhu
Starting Member
3 Posts |
Posted - 2009-07-02 : 19:28:36
|
| We are dynamically creating tables. Because we don't know what data types will be in a column, we use all VARCHAR columns except for the index (ResID).However, we want to be able to run something like SELECT * FROM TABLE WHERE Value > 5Of course, this will require some conversion. This is an example of what I came up with to get the column I will filter on.select pivottest.ResID, pivottest.Row, pivottest.ColumnName, pivottest.[Value], CONVERT(Decimal(10,4), ij.[Value]) as NumericValuefrom pivottestINNER JOIN( select ResID, Row, ColumnName, [Value] from pivottest where PATINDEX('%[^0-9.]%', [Value]) < 1) ijON ij.ResID = pivottest.ResID AND ij.ColumnName = pivottest.ColumnName AND pivottest.Row = ij.RowNow this seems to work just peachy. NumericValue looks to be a decimal with 4 decimal places and everything was converted correctly. I am only getting rows that we will be able to filter on with a numeric comparison like '> 1'But, when I add that statement: select pivottest.ResID, pivottest.Row, pivottest.ColumnName, pivottest.[Value], CONVERT(Decimal(10,4), ij.[Value])from pivottestINNER JOIN( select ResID, Row, ColumnName, [Value] from pivottest where PATINDEX('%[^0-9.]%', [Value]) < 1) ijON ij.ResID = pivottest.ResID AND ij.ColumnName = pivottest.ColumnName AND pivottest.Row = ij.RowWHERE CONVERT(Decimal(10,4), ij.[Value]) > 15.1I get 'Error converting data type varchar to numeric.'It seems like maybe the optimizer is trying to flatten the query and run both WHERE clauses at the same time or something, so it is tripping on the non-numeric values that haven't been stripped out yet. Any idea what is going on here?If there is a better way to do a numeric comparison on a VARCHAR column I would be happy to use that, but I am still very curious as to what is causing my error with this query. |
|
|
jimf
Master Smack Fu Yak Hacker
2875 Posts |
Posted - 2009-07-02 : 19:59:45
|
| There may be a character in the column ij.value that is supposedly numeric.Does this return anythingSELECT * FROM pivottest where isnumeric(iValue) = 0 There may be a value with a comma in it that would break the conversionCONVERT(Decimal(10,4), replace(ij.[Value],',','')) would fix that.Jim |
 |
|
|
pikthulhu
Starting Member
3 Posts |
Posted - 2009-07-02 : 22:35:09
|
| I'll do you one better because I am just testing things on a dummy table for now. Here is the entire table.ResID Row ColumnName Value1 0 col1 11 0 col2 21 0 col3 g31 1 col1 111 1 col2 221 1 col3 331 2 col1 maxit1 2 col2 22.21 2 col3 3332 0 col1 412 0 col2 422 0 col4 4+32 1 col1 411ff2 1 col2 42G22 1 col4 53g32 2 col1 5112 2 col2 4222.22 2 col4 4333fHere is the result of the ij query: select ResID, Row, ColumnName, [Value]from pivottestwhere PATINDEX('%[^0-9.]%', [Value]) < 1ResID Row ColumnName Value1 0 col1 11 0 col2 21 1 col1 111 1 col2 221 1 col3 331 2 col2 22.21 2 col3 3332 0 col1 412 0 col2 422 2 col1 5112 2 col2 4222.2As you can see, there are no results that cannot be converted to a Decimal. In the very first query I post in the thread, I do exactly that. It is only when I try a cast in the outer WHERE clause that this fails. |
 |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2009-07-02 : 22:49:51
|
tryselect pivottest.ResID, pivottest.Row, pivottest.ColumnName, pivottest.[Value], CONVERT(Decimal(10,4), ij.[Value])from pivottestINNER JOIN( select ResID, Row, ColumnName, [Value] = case when PATINDEX('%[^0-9.]%', [Value]) < 1 then [Value] else NULL end from pivottest where PATINDEX('%[^0-9.]%', [Value]) < 1) ijON ij.ResID = pivottest.ResID AND ij.ColumnName = pivottest.ColumnName AND pivottest.Row = ij.RowWHERE CONVERT(Decimal(10,4), ij.[Value]) > 15.1 KH[spoiler]Time is always against us[/spoiler] |
 |
|
|
pikthulhu
Starting Member
3 Posts |
Posted - 2009-07-02 : 23:24:19
|
| Well that worked. Thank you very much. I see what you've changed, but I still don't understand the deep whys behind it. Is it the case, then, that the outer WHERE is scanning the entire of ij.[Value] then, not just the rows that fit the inner WHERE clause? |
 |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2009-07-02 : 23:29:18
|
you might be right that the engine flatten the query. By adding the case when . . the outer query will validate against the "case when PATINDEX('%[^0-9.]%', [Value]) < 1 then [Value] else NULL end" KH[spoiler]Time is always against us[/spoiler] |
 |
|
|
|
|
|
|
|