테이블에서 마지막 항목을 가져옵니다 -SQL
-
09-06-2019 - |
문제
SQL Server에는 기본적으로 프로세스를 통해 항목을 추적하는 히스토리 테이블이 있습니다. 항목에는 프로세스 전반에 걸쳐 변경되지 않는 고정 필드가 있지만 상태 및 ID를 포함한 몇 가지 다른 필드가있어 프로세스 단계가 증가함에 따라 증가합니다.
기본적으로 배치 참조가 주어진 각 항목의 마지막 단계를 검색하고 싶습니다. 그래서 내가한다면
Select * from HistoryTable where BatchRef = @BatchRef
배치의 모든 항목에 대한 모든 단계를 반환합니다.
ID 상태 BatchRef itemCount 1 1 Batch001 100 1 2 Batch001 110 2 1 Batch001 60 2 2 Batch001 100
그러나 내가 정말로 원하는 것은 다음과 같습니다.
ID 상태 BatchRef itemCount 1 2 Batch001 110 2 2 Batch001 100
편집 : Appologies- Markdown과 함께 작업 할 테이블 태그를 얻을 수없는 것 같아요 - 편지에 대한 도움을 따르고 미리보기에서 잘 보입니다.
해결책
테이블 디자인을 이해하기가 어렵습니다. 저는 당신의 구분자를 먹었다고 생각합니다.
이것을 처리하는 기본 방법은 고정 필드별로 그룹화하고 일부 미등록 값에 대해 최대 (또는 최소)를 선택하는 것입니다 (일반적으로 잘 작동합니다). 당신의 경우, i 생각한다 그룹이 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
다른 팁
테이블에 ID 열이 있다고 가정합니다 ...
select
top 1 <fields>
from
HistoryTable
where
BatchRef = @BatchRef
order by
<IdentityColumn> DESC
항목 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
SELECT id, status, BatchRef, MAX(itemcount) AS maxItemcount
FROM HistoryTable GROUP BY id, status, BatchRef
HAVING status > 1
WMD가 형식을 지정하는 방식으로 데이터를 디코퍼하는 것은 약간 어렵지만 SQL 2005의 일반적인 테이블 표현식으로 필요한 트릭을 가져올 수 있습니다.
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
편집 : 마지막 항목을 원한다고 가정했습니다. 모든 일괄. 하나의 배치에 필요한 경우 다른 답변 (상위 1 위와 내림차순을 주문)이 갈 길입니다.
이미 제안했듯이 쿼리를 재정렬하여 다른 방향으로 정렬하여 실제로 첫 번째 행을 가져 오기를 원할 것입니다. 그러면 아마도 같은 것을 사용하고 싶을 것입니다
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 지원이없는 다른 변형의 경우.
또한보십시오 이것 질문 행 선택에 대한 추가 토론에 대한 질문. 집계 함수 사용 max ()는 값 계산에 테이블 스캔이 필요한지 여부에 따라 더 빠르거나 빠르지 않을 수 있습니다.