views:

57

answers:

3

I have a sticky SQL issue and I'm not the best with SQL...

I have a table that has a varchar(40) column that has data in the following two formats:

nn-nnn1nnn00000
nn-nnn-nnn-0000

The second data type is outdated; however because they are outdated they need to be viewed first in order. It was recommended to me to substring the last 5 chars of the row, then cast it to a number and then perhaps, if the -0000 gets turned into a negative then the older ones will sort first. I'm not sure if this would work though...

The problem with sorting it normally is because as you can see in the new ones is a number in the 7th position. So when I try to sort I get:

nn-nnn-nnn-0001
nn-nnn-nnn-0002
nn-nnn-nnn-0003
nn-nnn1nnn00002 <-Should be 5th
nn-nnn2nnn00003 <-Should be 6th
nn-nnn3nnn00001 <-Should be 4th

Because this is for a asp .net page I was thinking about doing some crazy stuff with datatables but I know this would be better suited to be handled by SQL Server.

Is there a way to sort by the last five chars in a way where the older ones will show first while still allowing the new ones to sort next correctly?

I really don't want to do some weird stuff in a datatable...

Thanks a million!!!

+4  A: 

I would try with something like this (though it may be considered clunky):

Select
  Col, Case Left(Right(Col, 5), 1) When '-' Then 0 Else 1 End As Old
From
  Table
Order By
  Old, Col
g.d.d.c
I went with this approach...thanks to all for the help. I really appreciate it!!!
wali
+3  A: 

The Right 5 characters & Cast as Integer works perfectly (after modification!!)

Check this out..

With MyTable AS
(
SELECT 'nn-nnn-nnn-0001' as MyData
UNION SELECT 'nn-nnn-nnn-0002'
UNION SELECT 'nn-nnn-nnn-0003'
UNION SELECT 'nn-nnn1nnn00002'
UNION SELECT 'nn-nnn2nnn00003'
UNION SELECT 'nn-nnn3nnn00001'
)
SELECT *
FROM MYTable
ORDER BY CASE WHEN SUBSTRING (MyData, 11, 1) = '-' THEN 0 ELSE 1 END, 
    CAST (REPLACE (RIGHT (MyData, 5), '-', 0) AS INTEGER)

MyData
---------------
nn-nnn-nnn-0001
nn-nnn-nnn-0002
nn-nnn-nnn-0003
nn-nnn3nnn00001
nn-nnn1nnn00002
nn-nnn2nnn00003

(6 row(s) affected)
Raj More
The expected output looks to be -1,-2,-3 not the other way round?
Martin Smith
cast as VarChar(10)
Jeff O
I didn't see your edit and had it working with g.d.d.c's method. Thanks!
wali
+1  A: 

You can create computed column, use deterministic user defined function to able to create index for that column and use that column to sort.

Edit: I was just going to clarify that but i am not sure if it is weird enough for you!

Emrah GOZCU
Persisted computed columns would work well for this. +1 over my own answer.
Raj More
I'd have to assume that if he can't clean up the old data, they won't let him add columns to the tables...
Philip Kelley
@Raj More: Thanks, your answer quite well. @Philip Kelley: My point of view is to have kind of data to create indexes well. Since the data grows, some time in the near future, sorting whole table could take too much time that may cause blocking problems then availibity fails. For me, availability is the key, so if the design is wrong then nothing is correct right?
Emrah GOZCU
Absolutely--if you can modify the table structures, then do so. (Many problems posted on SO are best resovled by applying proper database design, but time and again we get "modifying the tables is not an option", and I've grown too accustomed to "treating the symptoms instead of the disease".)
Philip Kelley
I liked the idea "treating the symptoms instead of the disease" :) it supports my thinking about the issue. Choosing to treat the symptoms is just like fooling myself. But looks like you have a good overview about the SO. You should put that into CW, I'll be happy to join discussion. +1 from me.
Emrah GOZCU