SQL Server: как выбрать последние 3 строки в таблице, упорядоченные по desc, а затем отсортировать их по asc? - PullRequest
0 голосов
/ 20 марта 2019

У меня есть CTE с последними 3 строками таблицы, отсортированными по VersionNumber DESC. Как я могу отсортировать их в обратном порядке, чтобы иметь наименьшее значение VersionNumber из этих 3, чтобы всегда иметь порядок отображения 1?

В Microsoft SQL Server нет LIMIT ...

;WITH cte AS
(       
    SELECT  
        BSId, RevisedBSId, VersionNumber, 
        RANK() OVER (ORDER BY VersionNumber DESC) AS [DisplayOrder] 
    FROM
        cte
),
sortedctethree AS
(
    SELECT TOP 3 
        BSId, RevisedBSId, VersionNumber, DisplayOrder 
    FROM 
        sortedcte
)
SELECT *
FROM sortedctethree

Здесь DisplayOrder не так. Если я использую другой CTE, где я пытаюсь изменить порядок, это все равно неправильно.

Мне нужно только 3 строки. Но в ТОП 3 может быть также одна или две строки в результате. В этом случае мне всегда нужно иметь DisplayOrder 1 для наименьшего VersionNumber.

VersionNumber | DisplayOrder 
--------------+--------------
     2        |      2
     1        |      1

Как можно добиться? Заранее большое спасибо.

Ответы [ 4 ]

2 голосов
/ 20 марта 2019

попробуйте, как показано ниже, вам не нужен еще один

WITH cte AS
    (       
    SELECT  
       BSId, RevisedBSId, VersionNumber, 
        rank() OVER (ORDER BY VersionNumber DESC)  AS [DisplayOrder] from 
     table_name
)      
        SELECT  BSId, RevisedBSId, VersionNumber , DisplayOrder FROM cte
        where DisplayOrder<=3
        order by DisplayOrder
0 голосов
/ 20 марта 2019

Если нет разделов, это самый простой способ, вам не нужно знать rank или row_number в вашем подзапросе или CTE

SELECT ROW_NUMBER() OVER (ORDER BY VersionNumber) as DisplayOrder, VesionNumber FROM (
    SELECT TOP 3 VesionNumber from mytable
    ORDER BY VesionNumber DESC
) A 
ORDER BY VesionNumber ASC

Или используя ваш подход

;WITH cte AS
(       
    SELECT  
        BSId, RevisedBSId, VersionNumber, 
        RANK() OVER (ORDER BY VersionNumber DESC) AS [SelectOrder], 
        RANK() OVER (ORDER BY VersionNumber ASC) AS [DisplayOrder], 
    FROM
        cte
),
sortedctethree AS
(
    SELECT TOP 3 
        BSId, RevisedBSId, VersionNumber, DisplayOrder, SelectOrder
    FROM 
        sortedcte
    ORDER BY SelectOrder
)
SELECT *
FROM sortedctethree
ORDER BY DisplayOrder
0 голосов
/ 20 марта 2019

Если я правильно понял:

Если вы используете ROW_NUMBER () с данными, упорядоченными asc, то наименьшее значение будет иметь DisplayOrder = 1

;WITH cte AS
(       
    SELECT  
        BSId, RevisedBSId, VersionNumber, 
        ROW_NUMBER() OVER (ORDER BY VersionNumber ASC) AS [DisplayOrder] 
    FROM
        cte
)
    SELECT TOP 3 
        BSId, RevisedBSId, VersionNumber, DisplayOrder 
    FROM 
        sortedcte where [DisplayOrder] =1
0 голосов
/ 20 марта 2019

Вы можете попробовать следующий подход. Нумеруйте свои данные, используя DENSE_RANK () , упорядоченный по убыванию VersionNumber, затем выберите первые три строки и упорядочите их по возрастанию:

;WITH cte AS (       
    SELECT  
        BSId, 
        RevisedBSId, 
        VersionNumber, 
        DENSE_RANK() OVER (ORDER BY VersionNumber DESC) AS [DisplayOrder] 
    FROM YourTable
)
SELECT  
    BSId, 
    RevisedBSId, 
    VersionNumber
FROM cte
WHERE [DisplayOrder] <= 3
ORDER BY VersionNumber ASC
...