I agree with @Larnu, if you're going to be using this for comparisons as opposed to just display, you are way better off splitting up these values and storing them separately.
But given what you have, in either case you'd still have to have some logic to determine bigger or smaller. I like PARSENAME()
for this, then you can build out a numeric value for the version similar to how you would for an IP address.
Given this table and data:
CREATE TABLE #x(id int NOT NULL, name char(1), build varchar(32));
INSERT #x VALUES(1,'A','10.0.1703'),(2,'B','6.3.9600');
We can write a query like this (nested CTEs only to avoid running PARSENAME()
logic more than once):
DECLARE @criteria varchar(32) = '10.0.1703';
;WITH x AS
(
SELECT id, name, build FROM #x
UNION ALL
SELECT id = NULL, name = NULL, build = @criteria
),
y AS
(
SELECT id, name, build,
bn = PARSENAME(build,3)*10000000 + PARSENAME(build,2)*100000 + PARSENAME(build,1)
FROM x
)
SELECT id, name, build FROM y
WHERE bn < (SELECT bn FROM y WHERE id IS NULL);
This assumes:
- all your builds come from the same product, and so
- always contain the same number of "parts"
- don't ever contain characters
10.0.14393 > 10.0.1703