0

我有一张表INDICATORS,其中存储了性能指标的详细信息和当前分数。我有另一个表IND_HISTORIES存储指标分数的历史值。数据按设定的时间段(即每季度)存储INDICATORSIND_HISTORIES以建立评分/评级趋势。

IND_HISTORIES具有类似于此的列结构-

pk_IndHistId  fk_IndId  Score  DateSaved

还定义了评级级别,这意味着 1 到 3 的得分值是低,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表,以查找指标的最新“快照”值高于其第二近的“快照”值的位置。(如上所述,在确定过程中,最好也加入 Rating Levels 表,以便仅在分数增加导致 Rating Level 增加时才返回行。)

任何解决方案都应该与 SQL Server 2005 兼容。

4

1 回答 1

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
于 2013-04-15T05:51:27.253 回答