2012-03-05 41 views
1

我需要分析一些博客並確定用戶是否訪問過一次,休息一年並再次訪問。我想用符合上述標準的VisitId爲每一行(Y/N)添加一個標誌。如何確定兩個記錄是否相隔1年(使用時間戳)

我該如何去創建這個SQL?

這裏是我的領域,我認爲需要使用(通過分析每個行的第一頁的時間戳):

  • VisitID - 每次訪問都有一個唯一的ID(即12356 ,12345,16459)
  • UserID - 每個用戶都有一個ID(例如,steve = 1,ted = 2,mark = 12345等...)
  • TimeStamp - 看起來像這樣:2010-01-01 00 :32:30.000

select VisitID, UserID, TimeStamp from page_view_t where pageNum = 1;

謝謝 - 任何幫助將不勝感激。

+2

您使用的是什麼RDBMS? – JNK 2012-03-05 17:57:59

+5

你的意思是一年*或以上*,或*正好一年*? – 2012-03-05 17:58:04

+0

SQL Server是DBMS ...不知道它是否是關係型的 – tylercomp 2012-03-05 18:13:47

回答

5

你可以排名每個用戶的行,然後再加入排名列設置爲自身相鄰行比較:

; 
WITH ranked AS (
    SELECT 
    *, 
    rnk = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY TimeStamp) 
    FROM page_view_t 
), 
flagged AS (
    SELECT 
    *, 
    IsReturnVisit = CASE 
     WHEN EXISTS (
     SELECT * 
     FROM ranked 
     WHERE UserID = r.UserID 
      AND rnk = r.rnk - 1 
      AND TimeStamp <= DATEADD(YEAR, -1, r.TimeStamp) 
    ) 
     THEN 'Y' 
     ELSE 'N' 
    END 
    FROM ranked r 
) 
SELECT 
    VisitID, 
    UserID, 
    TimeStamp, 
    IsReturnVisit 
FROM flagged 

注:以上僅標誌回訪。

UPDATE

爲標誌一樣回訪的第一次訪問中,flagged CTE可以作如下修改:

… 
SELECT 
    *, 
    IsFirstOrReturnVisit = CASE 
    WHEN p.UserID IS NULL OR r.TimeStamp >= DATEADD(YEAR, 1, p.TimeStamp) 
    THEN 'Y' 
    ELSE 'N' 
    END 
FROM ranked r 
    LEFT JOIN ranked p ON r.UserID = p.UserID AND r.rnk = p.rnk + 1 
… 

參考,可能是有用的:

+1

謝謝Andriy!我正在測試它,但看起來像我需要知道的,我不知道ROW_NUMBER()! – tylercomp 2012-03-05 19:23:33

+0

測試完美! – tylercomp 2012-03-05 19:45:03

+0

@tylercomp:謝謝。是的,排名功能使您能夠編寫簡單的(但並非總是)有效的查詢。當我第一次意識到他們時,我真的很着迷。 – 2012-03-05 21:17:11

1

另一個人也較快,但因爲我需要時間來做到這一點,這是一個完全不同的方法,我還不如將它張貼:d。

SELECT pv2.VisitID, 
     pv2.UserID, 
     pv2.TimeStamp, 
     CASE WHEN pv1.VisitID IS NOT NULL 
      AND pv3.VisitID IS NULL 
     THEN 'YES' ELSE 'NO' END AS IsReturnVisit 
FROM page_view_t pv2 
LEFT JOIN page_view_t pv1 ON pv1.UserID = pv2.UserID 
          AND pv1.VisitID <> pv2.VisitID 
          AND (pv1.TimeStamp <= DATEADD(YEAR, -1, pv2.TimeStamp) 
           OR pv2.TimeStamp <= DATEADD(YEAR, -1, pv1.TimeStamp)) 
          AND pv1.pageNum = 1 
LEFT JOIN page_view_t pv3 ON pv1.UserID = pv3.UserID 
          AND (pv3.TimeStamp BETWEEN pv1.TimeStamp AND pv2.TimeStamp 
           OR pv3.TimeStamp BETWEEN pv2.TimeStamp AND pv1.TimeStamp) 
          AND pv3.pageNum = 1 
WHERE pv2.pageNum = 1 
+0

謝謝!太糟糕了我不能標記兩個是正確的:( – tylercomp 2012-03-05 19:46:05

+0

沒什麼大不了的感謝+ 1反正 – RealUlysse 2012-03-05 19:54:09

1

假設用戶的每次訪問的page_view_t表存儲用戶名和時間戳細節,下面的查詢將返回誰訪問過連續兩次訪問之間採取至少一年(365天)的休息用戶。

select t1.UserID 
from page_view_t t1 
where (
    select datediff(day, max(t2.[TimeStamp]), t1.[TimeStamp]) 
    from page_view_t t2 
    where t2.UserID = t1.UserID and t2.[TimeStamp] < t1.[TimeStamp] 
    group by t2.UserID 
) >= 365