SQL Server:如何选择desc排序的表中的最后3行,然后按asc排序?

时间:2019-03-20 12:12:26

标签: sql-server common-table-expression

我有一个CTE,该表的最后3行按VersionNumber DESC排序。如何将它们向后排序,以使{3}中最小的VersionNumber始终具有显示顺序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行。但在TOP 3中,结果也可以是一或两行。在这种情况下,我需要始终为最小的VersionNumber使用DisplayOrder 1。

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

如何实现?非常感谢。

4 个答案:

答案 0 :(得分:2)

尝试如下,您不需要其他的CTE

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

答案 1 :(得分:0)

您可以尝试下一种方法。使用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

答案 2 :(得分:0)

如果我正确理解:

如果对数据按升序使用ROW_NUMBER(),则最小值将为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

答案 3 :(得分:0)

如果没有分区,这是最简单的方法,则您的子查询或CTE中不需要rank或row_number

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