我有一个表,记录每个用户的登录信息以及每次登录时该用户的当前总数。
我想做的是每天首次登录,并计算前几天总积分之间的积分差异。
为了使事情更清楚,我写了一个声明,每天每个用户的登录次数如下:
SELECT loginLog.username, A.logInDate, loginLog.pointsTotal
FROM loginLog
JOIN
(SELECT MIN(logID) AS logID, username, CAST(logInTime AS DATE) AS logInDate
FROM loginLog
GROUP BY username, CAST(logInTime AS DATE)) A
ON loginLog.logID = A.logID
ORDER BY username, logInDate DESC
产生以下结果集:
username logInDate pointsTotal
user1 2015-10-28 82685
user1 2015-10-27 51330
user1 2015-10-26 7810
user2 2015-10-28 221223
user2 2015-10-27 207234
user2 2015-10-26 178781
user3 2015-10-28 616120
user3 2015-10-27 598715
user3 2015-10-26 591289
user4 2015-10-28 187654
user4 2015-10-27 198378
user4 2015-10-26 115014
user5 2015-10-28 248138
user5 2015-10-27 224729
user5 2015-10-26 216229
user6 2015-10-28 68546
user6 2015-10-28 24139
user6 2015-10-27 33171
user6 2015-10-27 6459
user6 2015-10-26 6391
因此,例如,在第一条记录中,我想添加一列dailyGrowth,计算82685 - 51330,在第二条记录上,如果计算51330 - 7810等等。
这可能吗?
答案 0 :(得分:2)
由于您使用的是Sql Server 2012
,因此lead
窗口函数最简单:
DECLARE @t TABLE
(
username VARCHAR(10) ,
logInDate DATE ,
pointsTotal INT
)
INSERT INTO @t
VALUES ( 'user1', '2015-10-28', 82685 ),
( 'user1', '2015-10-27', 51330 ),
( 'user1', '2015-10-26', 7810 ),
( 'user2', '2015-10-28', 221223 ),
( 'user2', '2015-10-27', 207234 ),
( 'user2', '2015-10-26', 178781 )
select *, pointsTotal - lead(pointsTotal) over(partition by username order by logInDate desc) AS dailyGrowth
from @t
输出:
username logInDate pointsTotal dailyGrowth
user1 2015-10-28 82685 31355
user1 2015-10-27 51330 43520
user1 2015-10-26 7810 NULL
user2 2015-10-28 221223 13989
user2 2015-10-27 207234 28453
user2 2015-10-26 178781 NULL
使用现有查询:
select *, pointsTotal - lead(pointsTotal) over(partition by username order by logInDate desc) AS dailyGrowth
from (existing query goes here)t
答案 1 :(得分:0)
使用相关子查询查找上一行pointsTotal
:
select t1.username, t1.logInDate, t1.pointsTotal,
t1.pointsTotal - (select TOP 1 t2.pointsTotal
from tablename t2
where t2.username = t1.username
and t2.logInDate < t1.logInDate
order by t2.logInDate desc)
from tablename t1
(SELECT TOP 1
是特定于SQL Server的.ANSI SQL方法是在fetch first 1 row only
子句之后添加ORDER BY
。其他一些dbms产品则改为LIMIT 1
。)
答案 2 :(得分:0)
假设您的问题中的结果视图(使用pointsTotal)被称为SELECT username,p1.loginDate, p1.pointsTotal-p2.PointsTotal AS dailyGrowth
FROM loginPoints p1 inner join loginPoints p2 on
p1.username=p2.username AND DATEADD(day,1,p2.loginDate)=p1.loginDate
,您可以使用用户名和日期将自己加入表中。要获得下一个日期,您可以使用DATEADD
:
DATEADD
请注意,根据您使用的DBMS,{{1}}功能可能略有不同。
答案 3 :(得分:0)
在上述查询中创建一个视图,然后使用获取下一行值的分析lead()
函数,然后计算第一个值的差异。
详情here