2013-04-15 2 views
0

성능 지표의 세부 정보와 현재 점수를 저장하는 테이블 INDICATORS이 있습니다. 나는 표시기 점수의 역사적 가치를 저장하는 또 다른 테이블 IND_HISTORIES을 가지고있다. 데이터는 INDICATORS에서 IND_HISTORIES까지 설정 기간 (즉, 분기 별)에 저장되어 점수/등급 추세를 설정합니다.TSQL - 로깅 테이블의 가장 최근 두 행의 값을 비교해야합니다.

IND_HISTORIES는 1 내지 3의 점수의 값을 의미 정의

pk_IndHistId fk_IndId Score DateSaved 

등급 수준 this- 유사한 컬럼 구조를 갖는 것은 4~6은 평균이고,도 7 내지도 9는 높고 낮음이다.

가장 최근의 등급 (IND_HISTORIES 기준)을 기준으로 가장 최근의 등급이 두 번째로 최근의 등급보다 큰 경우 (두 번째로 최근 IND_HISTORIES 점수). 나는 등급 수준의 임계 값에 점수 값을 변환하는 임시 테이블을 만들 다음과 같은 코드를 사용하고

...

-- opt_IND_ScoreValues = 1;2;3;4;5;6;7;8;9 
DECLARE @tblScores TABLE (idx int identity, val int not null) 
INSERT INTO @tblScores (val) SELECT IntValue FROM dbo.fn_getSettingList('opt_IND_ScoreValues') 

-- opt_IND_RatingLevels = Low;Low;Low;Avg;Avg;Avg;High;High;High 
DECLARE @tblRatings TABLE (idx int identity, txt nvarchar(128)) 
INSERT INTO @tblRatings (txt) SELECT TxtValue FROM dbo.fn_getSettingList('opt_IND_RatingLevels') 

-- combine two tables above using a common index 
DECLARE @tblRatingScores TABLE (val int, txt nvarchar(128)) 
INSERT INTO @tblRatingScores SELECT s.val, r.txt FROM @tblScores s JOIN @tblRatings r ON s.idx = r.idx 

-- reduce table rows above to find score thresholds for each rating level 
DECLARE @tblRatingBands TABLE (idx int identity, score int not null, rating nvarchar(128)) 
INSERT INTO @tblRatingBands 
SELECT rs.val, rs.txt FROM @tblRatingScores rs 
INNER JOIN (SELECT MIN(val) as val FROM @tblRatingScores GROUP BY txt) AS x ON rs.txt = x.txt AND rs.val = x.val 
ORDER BY val 

질문 : 내가 IND_HISTORIES 테이블에 대해 실행할 수있는 우아한 쿼리가 있음 INDICATOR의 가장 최근 등급이 두 번째로 최근 등급보다 높은 레코드를 반환합니다.

업데이트 : 명확하게하기 위해 INDICATORS은 계산에 사용되지 않습니다. 이는 성능 측정 및 현재 '휘발성'점수에 대한 일반 정보를 보유하는 부모 테이블입니다. 점수는 주기적으로 IND_HISTORY에 저장됩니다. 이는 점수 추이를 설정하는 데 도움이되는 데이터의 특정 시점의 '스냅 샷'을 제공합니다.

IND_HISTORY 테이블을 쿼리하여 표시기의 가장 최근 '스냅 샷'값이 두 번째로 최신 '스냅 샷'값보다 높은 위치를 찾으려고합니다. (스코어 증가로 인해 등급 레벨이 증가하는 경우에만 행이 반환되도록 평가에서 위에 설명 된 등급 레벨 표를 결합하는 것이 이상적입니다.)

모든 솔루션은 SQL과 호환되어야합니다 서버 2005.

+0

명확히 할 수있는가요? 1. 계산에 'INDICATORS' 테이블이 사용 되었습니까? 설명에서 분명하지 않습니다. SQL 2012에 많은 Analytical 함수가 추가 되었기 때문에 태그에 SQL Server 버전을 추가 할 수 있습니까? 또한 테이블 값 함수를 사용하여 테이블에서 데이터를 가져 오는 이유가 무엇입니까? 모든 중간 함수 및 테이블 변수없이 소스 테이블에서 직접 선택하고 조인하지 마십시오. –

+0

업데이트가 추가되었습니다.귀하의 질문에 대해 잘 모르겠어요 : 테이블 가치 함수/중간 기능. 바라기를 나의 설명은 돕는다. – mjmoody383

+0

'dbo.fn_getSettingList ('opt_IND_ScoreValues')'는 테이블 값 함수입니다. 이것은'IND_HISTORY'와 관계가 있습니까? 테이블 값 함수와 테이블 변수가없는 테이블을'@tblScores'와 같이 직접 선택하지 않는 것 –

답변

0

다음을 구현했습니다. 작동하는 것 같습니다. 그러나 최적화 또는 통합 할 추천을 듣고 싶습니다.

먼저, 위의 임시 테이블 @tblRatingBands이 필요 없다는 것을 알고 있습니다. 대신, 아래에 설정된 첫 번째 쿼리에서 일치하는 텍스트 등급을 @tblRatingScores에서 선택하기 만하면됩니다.

마지막 쿼리에서 점수 값이 증가했는지, 등급 텍스트가 변경되었는지 확인합니다. 이는 트렌드 점수가 올라가고 등급 수준이 변경되었음을 나타냅니다.

DECLARE @tblTrendScores TABLE (indId int not null, ih_date datetime, rowNo int, ih_score int, rating nvarchar(128)); 

WITH LastTwoScores AS (
    SELECT fk_IndId, 
     DateSaved, 
     ROW_NUMBER() OVER (PARTITION BY fk_IndId ORDER BY DateSaved DESC) AS RowNo, 
     Score 
    FROM Ind_History 
) 
INSERT INTO @tblTrendScores 
SELECT *, 
     (SELECT txt FROM @tblRatingScores WHERE val = Score) 
FROM LastTwoScores 
WHERE RowNo BETWEEN 1 AND 2 
ORDER BY fk_IndId, RowNo 

SELECT a.indId, 
     a.ih_date, 
     CASE WHEN ((a.ih_score > IsNull(b.ih_score, 0)) AND (a.rating <> IsNull(b.rating, 'none'))) THEN 'Up' 
      WHEN ((a.ih_score < IsNull(b.ih_score, 0)) AND (a.rating <> IsNull(b.rating, 'none'))) THEN 'Down' 
      ELSE 'no-change' 
     END AS TrendRatingChange 
FROM @tblTrendScores a 
    JOIN @tblTrendScores b ON a.indId = b.indId AND b.rowNo = 2 
WHERE a.rowNo = 1 
+0

나는 테이블 변수가 필요 없다고 생각한다. CROSS APPLY를 사용하여 함수에 조인을 효과적으로 할 수 있습니다 (문제인 경우). 하지만 당신이 문제를 분류했기 때문에 기쁩니다. –

관련 문제