SQL 服务器数据库中有效时间范围之间的总分
Sum score between an effective time range in SQL Server database
我在 SQL 服务器数据库中有以下示例数据。
UserID Score StartDate EndDate
------------------------------------
1 10 2019-06-01 2019-07-15
1 20 2019-06-20 2019-07-01
1 30 2019-06-17 2019-07-25
2 10 2019-05-15 2019-06-10
2 20 2019-06-15 2019-07-01
2 30 2019-06-20 2019-07-15
我需要达到以下结果。
UserID ScoreTotal StartDate EndDate
----------------------------------------
1 10 2019-06-01 2019-06-17
1 40 2019-06-17 2019-06-20
1 60 2019-06-20 2019-07-01
1 40 2019-07-01 2019-07-15
1 30 2019-07-15 2019-07-25
2 10 2019-05-15 2019-06-10
2 20 2019-06-15 2019-06-20
2 50 2019-06-20 2019-07-01
2 30 2019-07-01 2019-07-15
startdate
或enddate
的分数是否包含在每次计算中都无关紧要。
非常感谢任何帮助。
假设您的关系是 A
,以下查询执行您需要的操作:
WITH unwrapped AS (
SELECT UserID, SUM(Score) AS Score, StartDate AS TempDate
FROM A
GROUP BY UserID, StartDate
UNION ALL
SELECT UserID, SUM(-1*Score) AS Score, EndDate AS TempDate
FROM A
GROUP BY UserID, EndDate
)
SELECT uw1.UserID, SUM(uw1.Score) AS ScoreTotal, MAX(uw1.TempDate) AS StartDate, uw2.TempDate AS EndDate
FROM unwrapped uw1 INNER JOIN unwrapped uw2
ON uw1.UserID = uw2.UserID AND uw1.TempDate < uw2.TempDate
GROUP BY uw1.UserID, uw2.TempDate;
如果我没理解错的话,你想按分数不变的时间段累计分数。这有点棘手,因为它可能需要因数据库而异的日期算法。这个想法是反转值并使用聚合和 window 函数:
with tt as (
select userid, score, startdate as dte
from t
union all
select userid, -score, enddate as dte
from t
) t
select userid, sum(sum(score)) over (partition by userid order by (dte)) as score,
dte, lead(dte) over (partition by userid order by dte)
from tt
group by userid, dte
我在 SQL 服务器数据库中有以下示例数据。
UserID Score StartDate EndDate
------------------------------------
1 10 2019-06-01 2019-07-15
1 20 2019-06-20 2019-07-01
1 30 2019-06-17 2019-07-25
2 10 2019-05-15 2019-06-10
2 20 2019-06-15 2019-07-01
2 30 2019-06-20 2019-07-15
我需要达到以下结果。
UserID ScoreTotal StartDate EndDate
----------------------------------------
1 10 2019-06-01 2019-06-17
1 40 2019-06-17 2019-06-20
1 60 2019-06-20 2019-07-01
1 40 2019-07-01 2019-07-15
1 30 2019-07-15 2019-07-25
2 10 2019-05-15 2019-06-10
2 20 2019-06-15 2019-06-20
2 50 2019-06-20 2019-07-01
2 30 2019-07-01 2019-07-15
startdate
或enddate
的分数是否包含在每次计算中都无关紧要。
非常感谢任何帮助。
假设您的关系是 A
,以下查询执行您需要的操作:
WITH unwrapped AS (
SELECT UserID, SUM(Score) AS Score, StartDate AS TempDate
FROM A
GROUP BY UserID, StartDate
UNION ALL
SELECT UserID, SUM(-1*Score) AS Score, EndDate AS TempDate
FROM A
GROUP BY UserID, EndDate
)
SELECT uw1.UserID, SUM(uw1.Score) AS ScoreTotal, MAX(uw1.TempDate) AS StartDate, uw2.TempDate AS EndDate
FROM unwrapped uw1 INNER JOIN unwrapped uw2
ON uw1.UserID = uw2.UserID AND uw1.TempDate < uw2.TempDate
GROUP BY uw1.UserID, uw2.TempDate;
如果我没理解错的话,你想按分数不变的时间段累计分数。这有点棘手,因为它可能需要因数据库而异的日期算法。这个想法是反转值并使用聚合和 window 函数:
with tt as (
select userid, score, startdate as dte
from t
union all
select userid, -score, enddate as dte
from t
) t
select userid, sum(sum(score)) over (partition by userid order by (dte)) as score,
dte, lead(dte) over (partition by userid order by dte)
from tt
group by userid, dte