2015-02-25 4 views
5

Я просмотрел другие вопросы и не могу найти то, что я ищу. У меня есть база данных SQL, а в ней - таблица InventoryAllocations. В таблице у меня есть несколько записей для DocumentID и вы хотите получить последнюю запись для каждого уникального DocumentID. Я могу получить только один, делаяSQL SELECT TOP 1 ДЛЯ КАЖДОЙ ГРУППЫ

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's.I надеюсь, что вы можете помочь. Many Thanks Hannah x

+1

Вы пробовали следуя инструкциям на http://stackoverflow.com/questions/9618559/select-top-record-for-each-year? Я считаю, что TOP OVER PARTITION BY - это в основном шаблон, который вам нужен здесь. – Eterm

+0

Последняя запись - согласно колонке (-ам)? – jarlh

+0

Последняя запись может быть определена либо самой новой CreatedDate, либо самым большим UID для каждого уникального DocumentID. – Hannah

ответ

9
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); 
+0

Кажется, это именно то, что мне нужно. Огромное спасибо!! Спасибо всем остальным за то, что нашли время, чтобы посмотреть и прокомментировать x – Hannah

1

Это дает каждой записи строку, беря каждый идентификатор документа, а затем дает последнему created_date row_number из 1 и каждую строку до этого с шагом 1. Затем мы выбираем записи с rowno of 1 для получения последней созданной даты на документ ID:

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 
+0

Не сортируя по дате в предложении row_number, вы не можете быть уверены, что получите правильные результаты или даже согласованные результаты. – Dibstar

+0

Результаты были бы согласованы, просто не то, что хотел OP. Он должен был быть заказан RecordTimeStamp. –

3
You can use a RowNumber() Window Function. 

SELECT * FROM(
    SELECT 
      ROW_NUMBER() OVER(PARITION 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 
+0

«Я хочу получить последнюю запись для каждого уникального DocumentID» - это вернет наивысший идентификатор документа для каждого идентификатора, а не то, что изначально было запрошено! – Dibstar

+0

Вы правы, мой плохой я прочитал это по-другому. Я изменил раздел, и это должно сработать. Мне нравится использовать функции окна, поскольку они более эффективны. Надеюсь это поможет. – VB1

Смежные вопросы