Sql-Server

僅返回相關行中具有最大值的行

  • December 12, 2017

在下面的範例中,如何獲取交換 id 是相對於 reservationId 的最大值的行?我目前正在加入多個表以獲取客戶、預訂、房間等資訊。但是如果值高於該值,我不希望交換數為 1 的行。

   DECLARE @RoomExchange TABLE (ID INT IDENTITY(1,1), reservationID int, 
                    swapNumber int, oldRoom int, newRoom int)

INSERT INTO @RoomExchange (reservationID, swapNumber, oldRoom, newRoom)
SELECT 12, 1, 1,2   UNION ALL
SELECT 13, 1, 3,4   UNION ALL
SELECT 14, 1, 5,6   UNION ALL
SELECT 14, 2, 6,5   UNION ALL
SELECT 15, 1, 7,8   UNION ALL
SELECT 15, 2, 8,9   UNION ALL
SELECT 15, 3, 9,7   UNION ALL
SELECT 16, 1, 10,11

所以上面我只想要ID所在的行

1、2、4、7 和 8。

您可以使用視窗函式:

select id, reservationID swapNumber, oldRoom, newRoom
from (
   select id, reservationID swapNumber, oldRoom, newRoom
        , row_number() over (partition by reservationId
                             order by swapNumber desc) as rn
   from @RoomExchange
) as T
where rn = 1;

通過顛反向序順序,我們可以為每個分區選擇第一個。

我知道,這是一個老問題,但另一個解決方案是 FIRST_VALUE:

SELECT DISTINCT
      re.reservationID,
      FIRST_VALUE(re.id)         OVER (PARTITION BY re.reservationID ORDER BY re.swapNumber DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) id,
      FIRST_VALUE(re.newRoom)    OVER (PARTITION BY re.reservationID ORDER BY re.swapNumber DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) room,
      FIRST_VALUE(re.swapNumber) OVER (PARTITION BY re.reservationID ORDER BY re.swapNumber DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) highest_swapNumber
 FROM @RoomExchange AS re

您將需要 DISTINCT,因為否則您將獲得雙倍記錄。阻止它在ROWS BETWEENtempdb 中創建工作表(它將對 default 執行什麼操作RANGE BETWEEN...)。當然還有一個LAST_VALUE()函式,可以類似地使用(除了DESC排序順序)),但據我所知,它總是使用 tempdb,因此速度較慢。

引用自:https://dba.stackexchange.com/questions/133599