문제

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 ()는 값 계산에 테이블 스캔이 필요한지 여부에 따라 더 빠르거나 빠르지 않을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top