SQL 为每个组选择前 1 个

问题描述 投票:0回答:4

我浏览了其他问题,但无法完全找到我要找的内容。我有一个 SQL 数据库,其中有一个名为 InventoryAllocations 的表。在表中,我有多个 DocumentID 条目,并且想要检索每个唯一 DocumentID 的最后一个条目。我可以通过这样做只检索一个

SELECT  top(1) [UID]
      ,[RecordStatusID]
      ,[CreatedDate]
      ,[CreatedTime]
      ,[CreatedByID]
      ,[OperationType]
      ,[InventoryLocationID]
      ,[DocumentTypeID]
      ,[DocumentID]
      ,[SOJPersonnelID]
      ,[InventorySerialisedItemID]
      ,[TransactionQty]
      ,[TransactionInventoryStatusID]
      ,[Completed]
      ,[CreatedByType]
      ,[RecordTimeStamp]
  FROM [CPData].[dbo].[InventoryAllocations]
  order by DocumentID desc

但我希望它返回一个包含所有唯一 DocumentID 的列表。我希望你能提供帮助。非常感谢汉娜x

sql sql-server greatest-n-per-group
4个回答
59
投票
SELECT TOP 1 WITH TIES 
    [UID]
    ,[RecordStatusID]
    ,[CreatedDate]
    ,[CreatedTime]
    ,[CreatedByID]
    ,[OperationType]
    ,[InventoryLocationID]
    ,[DocumentTypeID]
    ,[DocumentID]
    ,[SOJPersonnelID]
    ,[InventorySerialisedItemID]
    ,[TransactionQty]
    ,[TransactionInventoryStatusID]
    ,[Completed]
    ,[CreatedByType]
    ,[RecordTimeStamp]
FROM 
    [CPData].[dbo].[InventoryAllocations]
ORDER BY
    ROW_NUMBER() OVER(PARTITION BY DocumentID ORDER BY [RecordTimeStamp] DESC);

TOP 1
WITH TIES
一起使用。

WITH TIES
表示当
ORDER BY = 1
时,
SELECT
会获取该记录(因为
TOP 1
)以及所有其他具有
ORDER BY = 1
的记录(因为
WITH TIES
)。


10
投票
You can use a RowNumber() Window Function.

SELECT * FROM(
    SELECT 
            ROW_NUMBER() OVER(PARTITION BY [DOCUMENTID] ORDER BY [RecordTimeStamp] DESC) AS RowNumber, 
          ,[RecordStatusID]
          ,[CreatedDate]
          ,[CreatedTime]
          ,[CreatedByID]
          ,[OperationType]
          ,[InventoryLocationID]
          ,[DocumentTypeID]
          ,[DocumentID]
          ,[SOJPersonnelID]
          ,[InventorySerialisedItemID]
          ,[TransactionQty]
          ,[TransactionInventoryStatusID]
          ,[Completed]
          ,[CreatedByType]
          ,[RecordTimeStamp]
      FROM [CPData].[dbo].[InventoryAllocations] ) as A 
WHERE RowNumber = 1

 

1
投票

这为每条记录提供一行,获取每个文档 ID,然后为最新的创建日期赋予 row_number 1,并且在此之前的每一行递增 1。然后,我们选择 rowno 为 1 的记录来获取每个记录的最新创建日期文件编号:

SELECT [UID]
,[RecordStatusID]
,[CreatedDate]
,[CreatedTime]
,[CreatedByID]
,[OperationType]
,[InventoryLocationID]
,[DocumentTypeID]
,[DocumentID]
,[SOJPersonnelID]
,[InventorySerialisedItemID]
,[TransactionQty]
,[TransactionInventoryStatusID]
,[Completed]
,[CreatedByType]
,[RecordTimeStamp]
FROM
(
SELECT  
[UID]
,[RecordStatusID]
,[CreatedDate]
,[CreatedTime]
,[CreatedByID]
,[OperationType]
,[InventoryLocationID]
,[DocumentTypeID]
,[DocumentID]
,[SOJPersonnelID]
,[InventorySerialisedItemID]
,[TransactionQty]
,[TransactionInventoryStatusID]
,[Completed]
,[CreatedByType]
,[RecordTimeStamp]
,ROW_NUMBER() OVER (PARTITION BY DOCUMENT_ID ORDER BY CreatedDate) DESC AS ROWNO
FROM [CPData].[dbo].[InventoryAllocations] 
)
WHERE ROWNO = 1

0
投票

基本上是这样的。

with cte as
(
    SELECT [UID]
        , [RecordStatusID]
        , [CreatedDate]
        , [CreatedTime]
        , [CreatedByID]
        , [OperationType]
        , [InventoryLocationID]
        , [DocumentTypeID]
        , [DocumentID]
        , [SOJPersonnelID]
        , [InventorySerialisedItemID]
        , [TransactionQty]
        , [TransactionInventoryStatusID]
        , [Completed]
        , [CreatedByType]
        , [RecordTimeStamp]
        , ROW_NUMBER() over (partition by DocumentID order by DocumentID desc) as RowNum
    FROM   [CPData].[dbo].[InventoryAllocations]
)

select [UID]
    , [RecordStatusID]
    , [CreatedDate]
    , [CreatedTime]
    , [CreatedByID]
    , [OperationType]
    , [InventoryLocationID]
    , [DocumentTypeID]
    , [DocumentID]
    , [SOJPersonnelID]
    , [InventorySerialisedItemID]
    , [TransactionQty]
    , [TransactionInventoryStatusID]
    , [Completed]
    , [CreatedByType]
    , [RecordTimeStamp]
from cte
where RowNum = 1
order by DocumentID desc
© www.soinside.com 2019 - 2024. All rights reserved.