2008-08-27 71 views
4

我在SQL Server中有一個歷史表,它基本上跟蹤了一個流程中的項目。該項目有一些固定的字段,在整個過程中不會改變,但有一些其他字段,包括狀態和Id,隨着過程步驟的增加而增加。獲取表中的最後一項 - SQL

基本上我想檢索給定一個批處理引用的每個項目的最後一步。所以,如果我做了

Select * from HistoryTable where BatchRef = @BatchRef 

這將返回所有步驟批中的所有項目 - 如

 
Id  Status BatchRef  ItemCount 
1  1  Batch001  100 
1  2  Batch001  110 
2  1  Batch001  60 
2  2  Batch001  100 

但我真正想要的是:

 
Id  Status BatchRef  ItemCount 
1  2  Batch001  110 
2  2  Batch001  100 

編輯: Appologies--似乎無法讓TABLE標籤與Markdown一起工作 - 跟隨着對這封信的幫助,並且在預覽中看起來很好

回答

6

很難理解你的餐桌設計 - 我認爲你吃了你的分隔符。

處理這個問題的基本方法是GROUP BY您的固定字段,並選擇一個MAX(或MIN)作爲某個unqiue值(日期時間通常工作正常)。在你的情況下,我認爲 GROUP BY將是BatchRef和ItemCount,並且Id將是您唯一的列。

然後,回到表格以獲取所有列。喜歡的東西:

SELECT * 
FROM HistoryTable 
JOIN (
    SELECT 
     MAX(Id) as Id. 
     BatchRef, 
     ItemCount 
    FROM HsitoryTable 
    WHERE 
     BacthRef = @batchRef 
    GROUP BY 
     BatchRef, 
     ItemCount 
) as Latest ON 
    HistoryTable.Id = Latest.Id 
10

假設你在表中標識列...

select 
    top 1 <fields> 
from 
    HistoryTable 
where 
    BatchRef = @BatchRef 
order by 
    <IdentityColumn> DESC 
0

這是一個有點難以正是DeCypher數據WMD已格式化的方式,但你可以拉的那種把戲,你需要用公用表表達式2005年SQL:

with LastBatches as (
    select Batch, max(Id) 
    from HistoryTable 
    group by Batch 
) 
select * 
from HistoryTable h 
    join LastBatches b on b.Batch = h.Batch and b.Id = h.Id 

或子查詢(在子查詢的作品假定組 - 從我的頭頂,我不記得):

select * 
from HistoryTable h 
    join (
     select Batch, max(Id) 
     from HistoryTable 
     group by Batch 
    ) b on b.Batch = h.Batch and b.Id = h.Id 

編輯:我是假設你想要t他最後的項目爲,每批次。如果你只需要一個批次,那麼其他答案(做一個頂部1,然後降序)是要走的路。

0

正如已經建議的,您可能想重新排序查詢以便在另一個方向對其進行排序,以便實際獲取第一行。然後,你可能想使用類似

SELECT TOP 1 ... 

如果你使用MSSQL 2K或更早版本,或兼容SQL變種

SELECT * FROM (
    SELECT 
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber, 
    columns 
    FROM tablename 
) AS foo 
WHERE rownumber = n 

任何其他版本(或其他數據庫系統是支持標準符號)或

SELECT ... LIMIT 1 OFFSET 0 

對於沒有標準SQL支持的其他變體。

另請參閱this有關選擇行的其他討論問題。根據計算值是否需要表掃描,使用聚合函數max()可能會也可能不會更快。

1

假設產品ID在增量編號:

--Declare a temp table to hold the last step for each item id 
DECLARE @LastStepForEach TABLE (
Id int, 
Status int, 
BatchRef char(10), 
ItemCount int) 

--Loop counter 
DECLARE @count INT; 
SET @count = 0; 

--Loop through all of the items 
WHILE (@count < (SELECT MAX(Id) FROM HistoryTable WHERE BatchRef = @BatchRef)) 
BEGIN 
    SET @count = @count + 1; 

    INSERT INTO @LastStepForEach (Id, Status, BatchRef, ItemCount) 
     SELECT Id, Status, BatchRef, ItemCount 
     FROM HistoryTable 
     WHERE BatchRef = @BatchRef 
     AND Id = @count 
     AND Status = 
     (
      SELECT MAX(Status) 
      FROM HistoryTable 
      WHERE BatchRef = @BatchRef 
      AND Id = @count 
     ) 

END 

SELECT * 
FROM @LastStepForEach 
1
SELECT id, status, BatchRef, MAX(itemcount) AS maxItemcount 
FROM HistoryTable GROUP BY id, status, BatchRef 
HAVING status > 1 
+0

通過標記的東西維基你剝奪你代表的自我,一般沒有必要。這個答案是一種工作 – 2011-10-31 05:23:25

相關問題