Oracle SQL to Sort Version Numbers
This is one way to do it. First order by the number before .
and then by the numbers after .
select version_number
from mytable
order by substr(version_number, 1, instr(version_number,'.')-1) desc
,length(substr(version_number, instr(version_number,'.')+1)) desc
,substr(version_number, instr(version_number,'.')+1) desc
How to sort version numbers (like 5.3.60.8)
I will show here the answer from AskTom, which can be used with different version size :
WITH inputs
AS (SELECT 1 as id, '6.0.5.94' as col FROM DUAL
UNION ALL
SELECT 2,'5.3.30.8' FROM DUAL
UNION ALL
SELECT 3,'5.3.4.8' FROM DUAL
UNION ALL
SELECT 4,'3' FROM DUAL
UNION ALL
SELECT 5,'3.3.40' FROM DUAL
UNION ALL
SELECT 6,'3.3.4.1.5' FROM DUAL
UNION ALL
SELECT 7,'3.3.4.1' FROM DUAL)
SELECT col, MAX (SYS_CONNECT_BY_PATH (v, '.')) p
FROM (SELECT t.col, TO_NUMBER (SUBSTR (x.COLUMN_VALUE, 1, 5)) r, SUBSTR (x.COLUMN_VALUE, 6) v, id rid
FROM inputs t,
TABLE (
CAST (
MULTISET (
SELECT TO_CHAR (LEVEL, 'fm00000')
|| TO_CHAR (TO_NUMBER (SUBSTR ('.' || col || '.', INSTR ('.' || col || '.', '.', 1, ROWNUM) + 1, INSTR ('.' || col || '.', '.', 1, ROWNUM + 1) - INSTR ('.' || col || '.', '.', 1, ROWNUM) - 1)), 'fm0000000000')
FROM DUAL
CONNECT BY LEVEL <= LENGTH (col) - LENGTH (REPLACE (col, '.', '')) + 1) AS SYS.odciVarchar2List)) x)
START WITH r = 1
CONNECT BY PRIOR rid = rid AND PRIOR r + 1 = r
GROUP BY col
ORDER BY p
SQL sort by version number, a string of varying length
For best results, refactor version number storage so that each section has it's own column: MajorVersion, MinorVersion, Revision, Build. Then the ordering problem suddenly becomes trivial. You can also build a computed column for easy retrieval of the full string.
Oracle DB version column sorting
SELECT * FROM YOUR_TABLE
ORDER BY
to_number(regexp_substr(COL1, '[^.]+', 1, 1)) DESC NULLS FIRST,
to_number(regexp_substr(COL1, '[^.]+', 1, 2)) DESC NULLS FIRST ,
to_number(regexp_substr(COL1, '[^.]+', 1, 3)) DESC NULLS FIRST ,
to_number(regexp_substr(COL1, '[^.]+', 1, 4)) DESC NULLS FIRST ;
How Can I Sort A 'Version Number' Column Generically Using a SQL Server Query
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
SQL Oracle Sort string (numbers) and (letters with numbers)
select column
from table
order by
regexp_substr(column, '^\D*') nulls first,
to_number(regexp_substr(column, '\d+'))
fiddle
Version number sorting in Sql Server
Implementation of Brain's Solution
Declare @tblVersion table(VersionNumber varchar(100))
Insert into @tblVersion Values('1.3.1')
Insert into @tblVersion Values('1.3.2.5')
Insert into @tblVersion Values('1.4.1.7.12')
Insert into @tblVersion Values('1.4.11.14.7')
Insert into @tblVersion Values('1.4.3.109.1')
Insert into @tblVersion Values('1.4.8.66')
--Select * From @tblVersion
;With CTE AS
(
Select
Rn = Row_Number() Over(Order By (Select 1))
,VersionNumber
From @tblVersion
)
,CTESplit AS
(
SELECT
F1.Rn,
F1.VersionNumber,
VersionSort =
Case
When Len(O.VersionSort) = 1 Then '000' + O.VersionSort
When Len(O.VersionSort) = 2 Then '00' + O.VersionSort
When Len(O.VersionSort) = 3 Then '0' + O.VersionSort
When Len(O.VersionSort) = 4 Then O.VersionSort
End
FROM
(
SELECT *,
cast('<X>'+replace(F.VersionNumber,'.','</X><X>')+'</X>' as XML) as xmlfilter from CTE F
)F1
CROSS APPLY
(
SELECT fdata.D.value('.','varchar(50)') as VersionSort
FROM f1.xmlfilter.nodes('X') as fdata(D)) O
)
,CTE3 As(
Select
--Rn
--,
VersionNumber
,SortableVersion =
Stuff(
(Select '.' + Cast(VersionSort As Varchar(100))
From CTESplit c2
Where c2.Rn = c1.Rn
For Xml Path('')),1,1,'')
From CTESplit c1
Group By c1.Rn,c1.VersionNumber
)
Select VersionNumber
From CTE3
Order By SortableVersion
Oracle sql Order By number and char inside
The immediate problem is that you are incrementing the positionas well as the occurrence; so
REGEXP_SUBSTR(string, '\d', 2, 2)
should be
REGEXP_SUBSTR(string, '\d', 1, 2)
But you're overcomplicating it, and not handling multiple-digit elements, either when extracting or when sorting as nothing is treated as a number.
I think this does what you want:
ORDER BY
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 1)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 2)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 3)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 4)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 5)) nulls first,
string
db<>fiddle
If only the first element can start with a character (or characters), then you just just add a check for that after the first digit:
ORDER BY
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 1)) nulls first,
REGEXP_SUBSTR(string, '^\w+', 1, 1) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 2)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 3)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 4)) nulls first,
TO_NUMBER(REGEXP_SUBSTR(string, '\d+', 1, 5)) nulls first
which will order 3,A3,A3.1,B3
.
You might not need the string
at the end now.
db<>fiddle
ORACLE Order By number first in string field
When I run your example in my database I get the 'correct' sort order as per your list. Check you NLS_SORT setting; mine is set to BINARY.
Try it out by changing it for the session;
ALTER SESSION SET nls_sort='BINARY';
There are lots of possibilities for this parameter so if you want to experiment you can find the possibilities in the V$NLS_VALID_VALUES view.
I've also just spotted that you can do the following;
SELECT * FROM table1 ORDER BY colb, NLSSORT(cola, 'NLS_SORT=BINARY')
Related Topics
Performance of Querying Across Two MySQL Databases on The Same Server
How to Generate All Constraints Scripts
How to Select The First 100 Characters in SQL Server
Error- Ora-22835: Buffer Too Small for Clob to Char or Blob to Raw Conversion
What Is The Advantage of Using Fast_Forward for Defining a Cursor
Need to Convert Text Field to Varchar Temporarily So That I Can Pass to a Stored Procedure
How to Update an Xml Attribute Value in an Xml Variable Using T-Sql
How to Search New Line Char in Oracle Table
How to Write SQL in a Migration in Rails
Refresh Materialized View Periodically Postgres
Sql Server Database Change Workflow Best Practices
Sql Server - Is Using @@Rowcount Safe in Multithreaded Applications
Creating a Db Table Null Best Practices
I Am Trying to Copy a File, But Getting Error Message
Order of Execution in SQL Server Variable Assignment Using Select
Call Dll Function from SQL Stored Procedure Using The Current Connection