Пометить записи с наибольшим номером версии в вычисляемом поле / вычисляемом столбце как «true», остальные как false - PullRequest
0 голосов
/ 28 сентября 2018

Среда: MS SQL Server 2016.

У меня есть таблица, которая содержит (Jasper Reports) представления компоновки, подобные этой (только соответствующие поля показаны для краткости):

ID        Name                          Key                           Version
  1       CoverLetter                   <guid1>                       1.00.00
  2       Contract                      <guid2>                       1.00.00
  3       CoverLetter                   <guid1>                       1.00.01

Цель:

Мне нужно дополнительное вычисляемое поле, в котором установлено значение true или false в зависимости от того, является ли запись самой высокой версией любого данного макета или нет (тот же макет, но разные версии имеют одинаковый ключ,разные макеты имеют разные ключи).

Например:

ID:       Name:                 Key:          Version:      isHighestVersion: (calculated field)
  1       CoverLetter           <guid1>       1.00.00       false
  2       Contract              <guid2>       1.00.00       true
  3       CoverLetter           <guid1>       1.00.01       true

Запрос SQL, который показывает только самые высокие версии каждого макета, выглядит следующим образом:

( SELECT TACMasterlayouts.*
FROM
  (SELECT
     TACMasterLayoutKey, MAX(TACMasterLayoutVersion) as TACMasterLayoutVersion
   FROM
     TACMasterlayouts
   GROUP BY
     TACMasterLayoutKey) AS latest_TACMasterLayouts
INNER JOIN
  TACMasterlayouts
ON
  TACMasterlayouts.TACMasterLayoutKey = latest_TACMasterLayouts.TACMasterLayoutKey AND
  TACMasterlayouts.TACMasterLayoutVersion = latest_TACMasterLayouts.TACMasterLayoutVersion
) 

Но мне нужны все записи - те, которые имеют наибольший номер версии на тот же ключ, помечены как true, а остальные помечены как false.

Что я уже сделал: Поиск в Google и SO, но ненайди что-нибудь подобное, что я мог бы превратить в то, что мне нужно.

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

Спасибо Джон, это указало мне правильное направление.

Это должно быть ПРАВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ - в противном случае отображаются только записи с самой высокой версией.

В качестве ссылки здесьполностью рабочий код:

SELECT TACMasterlayouts.*, CASE WHEN latest_TACMasterLayouts.TACMasterLayoutKey IS NOT NULL THEN 1  ELSE 0 END as isHighestVersion
FROM
  (SELECT TACMasterLayoutKey, MAX(TACMasterLayoutVersion) as TACMasterLayoutVersion
   FROM
     TACMasterlayouts
   GROUP BY
 TACMasterLayoutKey) AS latest_TACMasterLayouts
RIGHT OUTER JOIN
  TACMasterlayouts
ON
  TACMasterlayouts.TACMasterLayoutKey = latest_TACMasterLayouts.TACMasterLayoutKey AND
  TACMasterlayouts.TACMasterLayoutVersion = latest_TACMasterLayouts.TACMasterLayoutVersion
  ) 
0 голосов
/ 28 сентября 2018

Вам необходимо выполнить некоторый анализ, чтобы получить желаемый результат.

Сначала вы разбиваете номера версий на отдельные целые, затем присваиваете row_number на их основе, а затем на основе номера строки выпоместите 1-true или 0-false в дополнительный столбец, который я назвал IsLatest.

. В SQL Server нет true или false, вы можете использовать BIT тип данных, который имеетдва значения (как логическое): 1 и 0.

Попробуйте этот запрос:

declare @tbl table(ID int,Name varchar(20),[Key] varchar(10),Version varchar(10));
insert into @tbl values 
(1,'CoverLetter','<guid1>','1.00.00'),
(2,'Contract','<guid2>','1.00.00'),
(3,'CoverLetter','<guid1>','1.00.01');

select ID, [Key], [version],
       case when rn = 1 then 1 else 0 end IsLatest
from (
    select *,
           row_number() over (order by
             cast(substring([version], 1, FirstDot - 1) as int) desc,
             cast(substring([version], FirstDot + 1, SecondDot - FirstDot - 1) as int) desc,
             cast(substring([version], SecondDot + 1, 100) as int) desc) rn
    from (
        select ID, [Key], [version],
               charindex('.', [version]) FirstDot,
               charindex('.', [version], charindex('.', [version]) + 1) SecondDot
        from @tbl
    ) a
) a
0 голосов
/ 28 сентября 2018

Просто поменяйте ВНУТРЕННЕЕ СОЕДИНЕНИЕ на ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ

и используйте регистр в вашем Select EG

CASE WHEN latest_TACMasterLayouts.TACMasterLayoutKey IS NOT NULL THEN 1  ELSE 0 END as isHighestVersion
...