2013-01-09 83 views
1

我有一个有趣的SQL问题我会很感激一些建议。SQL查询,以确定何时达到阈值

我与列的表:

DateAdded 
Score 
Team 

用户将进入自己的得分但是他们不一定会为了(有些人可能会,如果他们不每天使用该系统进行回日期)。

将团队成绩的每个成员加在一起,达到阈值得分的团队首先获胜。

我想要一个查询,它会告诉我哪个团队首先达到了阈值以及在哪个日期。

+0

你有什么已经尝试过?你的意思是“回归约会”得分?如果分数可以随时添加,那么您如何知道何时达到阈值?例如,A队可能会在周三通过门槛,然后周四B队会在周二输入显示他们在前一天通过的数据。也许这不是你的意思,但你的描述不是很清楚。 – Pondlife

回答

2

我认为日发现的第一个记录,这是你想要的实现。

SELECT TOP 1 T1.Dateadded, T1.Team FROM Table1 T1 
JOIN Table1 T2 
    ON T1.Team = T2.Team 
    and T1.Dateadded >= T2.Dateadded 
GROUP BY T1.Dateadded, T1.Team 
HAVING SUM(T2.Score) >= @Threshold 
ORDER BY T1.Dateadded 

SQL Fiddle

+0

这确实是我所追求的 - 非常感谢 – Liath

1

您可以使用DENSE_RANK来确定达到阈值的最佳/第一队。

WITH CTE AS 
(
    SELECT 
    DateAdded, Score, Team, 
    DENSE_RANK() OVER (Order By DateAdded ASC, Score DESC) AS Rank 
    FROM dbo.TableName 
    WHERE 
    Score >= Threshold 
) 
SELECT 
    DateAdded, Score, Team 
FROM CTE 
WHERE 
    Rank = 1 

请注意,这可能会返回多个团队。

+0

鉴于他想知道谁达到了第一个门槛,您应该先按dateAdded排序,然后再按Score排序以获得排名。此外,问题还不清楚他是否有每个新分数的记录,或者他们是否在现有行中总结新分数;那会改变你的WITH查询 – beder

+1

@beder:但是我先按DateAdded排序然后按Score(也许你指的是我在宽限期编辑的第一个版本)。 –

+0

对不起,我认为它没有刷新当我评论 – beder

2

你需要的是累计和。而且,SQL Server 2008不支持它。好消息,SQL Server 2012确实如此。

所以,你可以用一个相关子查询做到这一点:

select team, min(dateadded) as FirstPastThreshold 
from (select dateadded, score, team, 
      (select sum(score) from t t2 where t2.team = t.team and t2.dateadded <= t.dateadded) as cumulativescore 
     from t 
    ) t 
where cumulativescore>= @threshhold 
group by team 
+2

cumscore是一个非常糟糕的命名选择......只是说 – beder

0

你可以添加一个第四列称为currentThresholdScore。当插入新记录时,当前阈值分数列将是该记录分数加上之前插入的所有记录的值。然后检查当前阈值分数是否超过发送邮件的阈值等。

+0

虽然这将工作,你需要重新计算可能是资源密集的时间列。我正在运行一次解决方案之后。 – Liath

0

您可以对此问题使用子查询。只需添加一列,它列出了当前得分加上过去成绩的总和查询,然后由超过阈值

Sql Fiddle

Use tempdb 
Create Table Scoring (DateAdded DateTime, Score INT, Team INT) 
INSERT Scoring SELECT GetDate(), 100, 1 
INSERT Scoring SELECT GetDate()+1, 150, 1 
INSERT Scoring SELECT GetDate()+1, 50, 2 
INSERT Scoring SELECT GetDate()+2, 75, 2 
INSERT Scoring SELECT GetDate()-10, 75, 2 


DECLARE @Threshhold INT 
SET @Threshhold = 125 

-- Table which includes a cumulative score 
;WITH tbl AS 
(
SELECT 
    Team, 
    DateAdded, 
    Score, 
    -- This column calculates the current score + the sum of past scores 
    IsNull((SELECT Sum(t2.Score) CumScore FROM Scoring t2 WHERE t2.Team = t.Team AND t2.DateAdded < t.DateAdded),0) 
    + Score AS CumScore 
FROM Scoring t 
) 

-- Find first record > threshold 
SELECT TOP 1 * FROM tbl 
WHERE CumScore >= @Threshhold 
ORDER BY DateAdded ASC