I’m not really smart from your description, however, the result can be achieved using the following query
select your_table.*
from your_table
join
(
select BlilShortName, max(billversion) bmax
from your_table
group by BlilShortName
) t on your_table.billversion = t.bmax and your_table.BlilShortName = t.BlilShortName
From my experience it can be faster in some cases when compared to row_number
solution which always uses sequential scan.
PERFORMANCE BONUS
Since there is a discussion regarding the efficiency I dare to add simple test
IF OBJECT_ID('dbo.GTable', 'U') IS NOT NULL DROP TABLE dbo.GTable
SELECT TOP 1000000
NEWID() id,
ABS(CHECKSUM(NEWID())) % 100 group_id,
ABS(CHECKSUM(NEWID())) % 10000 orderby
INTO GTable
FROM sys.sysobjects
CROSS JOIN sys.all_columns
SET STATISTICS TIME on
-- GROUP BY version
select t1.*
from gtable t1
join
(
SELECT group_id, max(orderby) gmax
from gtable
group by group_id
) t2 on t1.group_id = t2.group_id and t1.orderby = t2.gmax
-- WINDOW FUNCTION version
select t.id, t.group_id, t.orderby
from
(
select *,
dense_rank() over (partition by group_id order by orderby desc) rn
from gtable
) t
where t.rn = 1
If I run this on my server then the performance of GROUP BY version is more than twice better than the window function version. Moreover, if I create index
CREATE NONCLUSTERED INDEX ix_gtable_groupid_orderby
ON [dbo].[GTable] (group_id,orderby) INCLUDE (id)
then the performance is even more than three times better, whereas the performance of window function solution is the same since it uses sequential scan despite the index.