SQL Server: как сортировать и сравнивать множество версий?

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

SQL Server: как сортировать и сравнивать множество версий?

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?

Можете ли вы опубликовать некоторые образцы данных и ожидаемые результаты, пожалуйста? Кроме того, одна из этих ссылок предназначена для MySQL, которая представляет собой совершенно другую СУБД для SQL Server; что вы на самом деле используете? Однако в идеале, если вы храните номера версий в данных, лучше хранить их в разных частях, а не в 1. Т.е. иметь 4 столбца, такие как MajorVersionNumber, MinorVersionNumber, BuildNumber, RevisionNumber.

Larnu 25.02.2019 11:41

(я добавил это в описание вопроса) Я использую SQL Server. Пример строк, необходимых для результата: введите здесь описание изображения id name build(version) 1 A 10.0.1703 2 B 6.3.9600 Мне нужно найти все версии старше или равные 10.0.1703 . 6.3.9600 меньше 10.0.1703

smpr 25.02.2019 11:56

Хорошо, теперь нам просто нужно подтверждение используемой вами СУБД. Я не хочу давать ответ T-SQL, а затем узнавать, что вы используете MySQL. Если запустить PRINT @@VERSION; что возвращается?

Larnu 25.02.2019 12:01

Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) — 14.0.3048.4 (X64) 30 ноября 2018 г. 12:57:58 Copyright (C) Microsoft Corporation Enterprise Edition 2017 (64-разрядная версия) в Windows Server 2016 Standard 10.0 <X64> (Сборка 14393:)

smpr 25.02.2019 12:04
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
4
179
2

Ответы 2

один из способов - сыграть как hierarchyid

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

ДЕМО

Спасибо, этот запрос работает, но пропускает много строк со сборками (версиями), такими как 10.0.14393, 5.2.3790, 10.0.15063 и т. д.

smpr 25.02.2019 12:41

@smpr - возвращает 5.2.3790 (демо rextester.com/CAIKQ32951), и правильно, что два других пропущены. Они выше, чем 10.0.1703. И 14393, и 15063 больше, чем 1703, поэтому они имеют одинаковые основные и второстепенные версии, а также более поздние версии патчей.

Martin Smith 25.02.2019 13:03

Я согласен с @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

Другие вопросы по теме