2015-10-28 39 views
0

我有一個表記錄每個用戶的登錄數以及該用戶在每次登錄時的當前積分總數。SQL - 計算兩條記錄之間的差異

我想要做的是每天獲得他們的第一次登錄,並計算他們以前的日子的積分之間的積分差異。

爲了讓事情更清晰,我寫了每天獲取每個用戶的分鐘登錄的聲明如下:

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等等。

這是poss IBLE?

+0

請標明使用的dbms產品。 (有些非ANSI SQL ......) – jarlh

回答

2

由於您使用Sql Server 2012lead窗函數是最容易在這裏:

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 
+0

哇,我不知道主導函數。非常強大的東西!謝謝 – CPB07

+0

那麼也可以應用於計算每日增長百分比? – CPB07

+0

當然:'pointsTotal * 100.0/lead(pointsTotal)over(按用戶名順序劃分logInDate desc)AS dailyGrowth2' –

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的方式是ORDER BY子句後添加fetch first 1 row only一些其他DBMS產品有LIMIT 1代替。 )

0

假設您的問題中的結果視圖(與pointsTotal)被稱爲loginPoints,您可以使用用戶名和日期將自己加入表中。爲了讓您可以使用DATEADD下一個日期:

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 

需要注意的是,這取決於DBMS使用,該DATEADD功能可能會稍有不同。

+0

該表名爲loginLog,其中包含所有有問題的字段(logID,username,pointsTotal,logInTime) – CPB07

0

在上述查詢中創建一個視圖,然後使用分析lead()函數獲取下一行值,然後計算第一個值的差值。

詳細here

相關問題