views:

50

answers:

3

I wonder if the SQL geniuses amongst us could lend me a helping hand.

I have a column VersionNo in a table Versions that contains 'version number' values like

VersionNo
---------
1.2.3.1
1.10.3.1
1.4.7.2

etc.

I am looking to sort this, but unfortunately, when I do a standard order by, it is treated as a string, so the order comes out as

VersionNo
---------
1.10.3.1
1.2.3.1
1.4.7.2

Intead of the following, which is what I am after:

VersionNo
---------
1.2.3.1
1.4.7.2
1.10.3.1

So, what I need to do is to sort by the numbers in reverse order (e.g. in a.b.c.d, I need to sort by d,c,b,a to get the correct sort ourder).

But I am stuck as to how to achieve this in a GENERIC way. Sure, I can split the string up using the various sql functions (e.g. left, right, substring, len, charindex), but I can't guarantee that there will always be 4 parts to the version number. I may have a list like this:

VersionNo
---------
1.2.3.1
1.3
1.4.7.2
1.7.1
1.10.3.1
1.16.8.0.1

Can, does anyone have any suggestions? Your help would be much appreciated.

A: 

If you can, alter the schema so that the version has 4 columns instead of one. Then sorting is easy.

tdammers
Haha, yeah, that occurred to me, unfortunately, that is not an option. Also, the length may be variable, and I can't guarantee the maximum number of columns will 4, or anything else, really.
James Wiseman
If you're using SQL Server 2005 (may be 2008, need to double-check) or newer, you can write a .NET CLR method to do the comparison, or better yet, transform an arbitrary version number into a canonical, sortable format (e.g. pad every part to, say, 5 digits); register this CLR method with your DB and you can call it like a regular SQL function. Otherwise, you're stuck with implementing the same thing in SQL, which is probably bad for your performance.
tdammers
Yeah, unfortunately its an old in-house app in VB6 and SQL 2000.
James Wiseman
A: 

Depending on SQL engine for MySQL would be sth like this:

SELECT versionNo FROM Versions
ORDER BY
SUBSTRING_INDEX(versionNo, '.', 1) + 0,
SUBSTRING_INDEX(SUBSTRING_INDEX(versionNo, '.', -3), '.', 1) + 0,
SUBSTRING_INDEX(SUBSTRING_INDEX(versionNo, '.', -2), '.', 1) + 0,
SUBSTRING_INDEX(versionNo, '.', -1) + 0;

For MySQL version 3.23.15 an above

SELECT versionNo FROM Versions ORDER BY INET_ATON(ip);
cichy
Its SQL Server as the tag indicates, but have updated my question accordingly.
James Wiseman
+4  A: 

If You are using SQL Server 2008

select VersionNo from Versions order by cast('/' + replace(VersionNo , '.', '/') + '/' as hierarchyid);

What is hierarchyid

Edit:

Solutions for 2000, 2005, 2008: Solutions to T-SQL Sorting Challenge here.

The challenge

Vash
Would that it were. But I'm stuck with old SQL 2000, unfortunately.
James Wiseman
@James Wiseman: In the link You should found the solution for You.
Vash
Brilliant! Thanks for the help. Tried it and it works.
James Wiseman
@James - Not sure what you ended up using. You can also use `parsename` for this as in this answer http://stackoverflow.com/questions/3057532/how-to-get-max-value-of-a-version-number-varchar-column-in-t-sql/3057547#3057547
Martin Smith
@Martin: I actually used this, but I like your suggestion as well. Thanks.
James Wiseman