Как отсортировать столбец «Номер версии» в общем, используя запрос SQL Server - PullRequest
12 голосов
/ 13 августа 2010

Интересно, могут ли гении SQL среди нас протянуть мне руку помощи?

У меня есть столбец VersionNo в таблице Versions, который содержит значения 'номера версии', такие как

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

и т. Д.

Я хочу отсортировать это, но, к сожалению, когда я делаю стандарт order by, он обрабатывается как строка, поэтому порядок выглядит как

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

Целое из следующего: вот что я ищу:

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

Итак, мне нужно отсортировать по номерам в обратном порядке (например, в abcd мне нужно отсортировать поd, c, b, a, чтобы получить правильную сортировку weder).

Но я застрял в том, как этого добиться ОБЩИМ способом.Конечно, я могу разбить строку, используя различные функции sql (например, left, right, substring, len, charindex), но я не могу гарантировать, что всегда будет 4 частиномер версии.У меня может быть такой список:

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

Может, у кого-нибудь есть предложения?Ваша помощь будет высоко ценится.

Ответы [ 4 ]

21 голосов
/ 13 августа 2010

Если вы используете SQL Server 2008

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

Что такое иерархия

Редактировать:

Решения для 2000, 2005, 2008: Решения для T-SQL Sorting Challenge здесь .

Задача

3 голосов
/ 13 августа 2010

В зависимости от механизма SQL для MySQL будет выглядеть примерно так:

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;

Для версии MySQL 3.23.15 и выше

SELECT versionNo FROM Versions ORDER BY INET_ATON(ip);
1 голос
/ 07 декабря 2017

Другой способ сделать это:

При условии, что у вас есть только a, b, c, d, вы можете также разделить данные на столбцы и сделать заказ по a, b, c, d (все desc) и получите 1 верхнюю строку

Если вам нужно увеличить до d, чтобы сказать e, f, g ... просто измените 1,2,3,4 на 1,2,3, 4,5,6,7 и т. Д. В запросе

Запрос: см. Демонстрацию

create table t (versionnumber varchar(255))
insert into t values
('1.0.0.505')
,('1.0.0.506')
,('1.0.0.507')
,('1.0.0.508')
,('1.0.0.509')
,('1.0.1.2')


; with cte as 
(
    select 
    column1=row_number() over (order by (select NULL)) ,
    column2=versionnumber
    from t
    )

select top 1
    CONCAT([1],'.',[2],'.',[3],'.',[4])
from 
(
    select 
        t.column1,
        split_values=SUBSTRING( t.column2, t1.N, ISNULL(NULLIF(CHARINDEX('.',t.column2,t1.N),0)-t1.N,8000)),
        r= row_number() over( partition by column1 order by t1.N) 
    from cte t 
        join
        (
            select 
                t.column2,
                1 as N 
            from cte t  
                UNION ALL
            select 
                t.column2,
                t1.N + 1 as N
            from cte t 
                join
                (
                 select 
                    top 8000
                        row_number() over(order by (select NULL)) as N 
                 from 
                    sys.objects s1 
                        cross join 
                   sys.objects s2 
                ) t1 
            on SUBSTRING(t.column2,t1.N,1) = '.'
         ) t1
          on t1.column2=t.column2
)a
pivot
( 
    max(split_values) for r in ([1],[2],[3],[4])
   )p
  order by [1] desc,[2] desc,[3] desc,[4] desc
0 голосов
/ 13 августа 2010

Если можете, измените схему так, чтобы в версии было 4 столбца вместо одного. Тогда сортировка проста.

...