SQL Server: как отсортировать и сравнить множество версий? - PullRequest
0 голосов
/ 25 февраля 2019

В моем запросе к таблице я должен найти все строки с версиями, где версии меньше или равны 10.0.1703 (<= 10.0.1703), и там есть множество версий.Я использую SQL Server.Пример строк, необходимых в результате: </p>

enter image description here

id | name | build(version)
--------------------------
1  | A    | 10.0.1703
2  | B    | 6.3.9600

Я должен найти все версии более старые или равные 10.0.1703.6.3.9600 меньше 10.0.1703

Это связано с этим вопросом, но предлагаемые решения мне сложно понять Как сравнивать версии программного обеспечения с использованием SQL Server?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Я согласен с @Larnu, если вы собираетесь использовать это для сравнения, а не просто для отображения, вам лучше разделить эти значения и хранить их отдельно.

Но учитывая то, что выв любом случае вам все равно придется иметь некоторую логику, чтобы определить больше или меньше.Мне нравится PARSENAME() для этого, тогда вы можете создать числовое значение для версии, аналогично тому, как вы делали бы для IP-адреса.

С учетом этой таблицы и данных:

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');

Мы можем написать такой запрос (вложенные CTE только для того, чтобы избежать выполнения логики PARSENAME() более одного раза):

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);

Это предполагает:

  • все ваши сборки получены изодин и тот же продукт, поэтому
    • всегда содержат одинаковое количество «частей»
    • никогда не содержат символов
  • 10.0.14393 > 10.0.1703
0 голосов
/ 25 февраля 2019

в одну сторону можно разыграть как hierarchyid

WHERE CAST('/' + build + '/' AS HIERARCHYID) <= CAST('/10.0.1703/' AS HIERARCHYID) 

DEMO

...