首页 > 解决方案 > 选择唯一的 SQL 语句

问题描述

我在名为 Lockers 的表中有以下数据(还有其他列,但现在让我们忽略它们)。

---------------------------------------
| ID    | LockerNo    | BookingID      |
----------------------------------------
| 1     | A01         | 111111         |
| 1     | A01         | 222222         |
| 1     | A01         | 333333         |
| 2     | A02         | 888888         |
| 2     | A02         | 999999         |
| 3     | A03         | 121212         |
| 3     | A03         | 232323         |
| 4     | A04         | 777777         |
| 5     | A05         | 555555         |
| 6     | A06         | 444444         |
----------------------------------------

上述输出由以下 SQL 生成:

Select LockerID, LockerNo, LBD.BookingID 
From Lockers L 
Inner Join LockerBookingDetails LBD On LBD.LockerID = L.ID  
Where Zone = 1 And IsActive = 1 
Order By L.LockerNo, LBD.BookingID 

我一直在努力创建一条 SQL 语句来显示以下输出。条件是获取最新的数据(假设BookingID是升序排序的)。

---------------------------------------
| ID    | LockerNo    | BookingID      |
----------------------------------------
| 1     | A01         | 333333         |
| 2     | A02         | 999999         |
| 3     | A03         | 232323         |
| 4     | A04         | 777777         |
| 5     | A05         | 555555         |
| 6     | A06         | 444444         |
----------------------------------------

标签: sqlsql-server

解决方案


一种替代方法是使用窗口函数,这将为您提供每个 LockerNO 的最大 BookingId:

SELECT
    Id, 
    LockerNo,
    BookingId
FROM
(
    SELECT
        ROWID = ROW_NUMBER() OVER(PARTITION BY LockerNO ORDER BY lbd.BookingId DESC),
        l.Id,
        l.LockerNo,
        lbd.BookingId
    FROM
        Lockers l 
        inner join LockerBookingDetails lbd on lbd.LockerID = l.ID  
    Where 
        Zone = 1 
        And IsActive = 1
) r
WHERE
    r.ROWID = 1

了解OVER子句和排名函数将对您有所帮助,请参阅 SQL Server 文档:

https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-2017


推荐阅读