MS-SQL中取用戶連續簽到的次數


表結構如下:

每個用戶每天只能簽到一次

現在前面的需求是判斷某個用戶在某天是否是連續簽到,使用sql中的遞歸來實現

with currentDateCTE AS (
 -- 當前天.
 SELECT
  *
 FROM
  dt_Signin
 WHERE
  user_id = 270 and CONVERT(DATE, sign_time)  = CONVERT(DATE, '2013-05-16 22:15:32.670')--這就是需求中的某天
),
prevDateCTE AS (
 -- 向前遞歸.
 SELECT
  *
 FROM
  currentDateCTE
 UNION ALL
 SELECT
  prevTab.*
 FROM
 (select * from dt_Signin  where user_id = 270) as  prevTab JOIN  prevDateCTE  
   ON (CONVERT(DATE,prevTab.sign_time)  = CONVERT(DATE,convert(char(20),dateadd(day,-1,prevDateCTE.sign_time),102))) 
),
nextDateCTE AS (
 -- 向后遞歸.
 SELECT
  *
 FROM
  currentDateCTE
 UNION ALL
 SELECT
  prevTab.*
 FROM
  (select * from dt_Signin  where user_id = 270) as prevTab JOIN  nextDateCTE  
   ON (CONVERT(DATE,prevTab.sign_time)  = CONVERT(DATE,convert(char(20),dateadd(day,+1,nextDateCTE.sign_time),102)))
)
SELECT
 --(SELECT MIN(sign_time) FROM prevDateCTE)  AS [第一天],
 --(SELECT MAX(sign_time) FROM nextDateCTE)  AS [最后一天],  
 DATEDIFF ( 
  dd,
  (SELECT MIN(sign_time) FROM prevDateCTE),
  (SELECT MAX(sign_time) FROM nextDateCTE)  
  ) + 1  AS signlxcount ---查詢連續簽到次數

原文如下:

判斷 “存在連續天數” 的處理

最近遇到一個問題, 說某個打卡的系統, 要打卡以后, 判斷是否存在 連續7天打卡。
例如 2012年1月7日 打卡了, 那么去檢查 2012年1月1日 至 2012年1月6日 是否都打了。
還存在這樣的情況, 可能是 2012年1月4日 至 2012年1月6日都打了, 同時 2012年1月8日 至 2012年1月10日都打了。
新打一個 2012年1月7日的卡, 形成了一個 連續7日。 ( 2012年1月4日 -- 2012年1月10日 )

處理思路是:
1. 從打卡日, 一天一天向前遞歸,直到遇到 上限值(例如這里的7天), 或者遇到中斷。
2. 從打卡日, 一天一天向后遞歸,直到遇到 上限值(例如這里的7天), 或者遇到中斷。
3. 獲取前面兩個步驟所產生的: 向前遞歸的最小值, 與向后遞歸的最大值。 來計算, 打卡日作產生的 連續天數。

CREATE TABLE #t (
id INT identity(1,1),
test_date DATETIME
)

INSERT INTO #t
SELECT CONVERT(DATETIME, '20120101', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120102', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120103', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120104', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120105', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120106', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120107', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120108', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120110', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120111', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120112', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120113', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120114', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120115', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120116', 112) UNION ALL
SELECT CONVERT(DATETIME, '20120117', 112);

with currentDateCTE AS (
-- 當前天.
SELECT
*
FROM
#t
WHERE
test_date = CONVERT(DATETIME, '20120106', 112)
),
prevDateCTE AS (
-- 向前遞歸.
SELECT
*
FROM
currentDateCTE
UNION ALL
SELECT
prevTab.*
FROM
#t prevTab JOIN prevDateCTE
ON (prevTab.test_date = prevDateCTE.test_date - 1)
),
nextDateCTE AS (
-- 向后遞歸.
SELECT
*
FROM
currentDateCTE
UNION ALL
SELECT
prevTab.*
FROM
#t prevTab JOIN nextDateCTE
ON (prevTab.test_date = nextDateCTE.test_date + 1)
)
SELECT
(SELECT MIN(test_date) FROM prevDateCTE) AS [第一天],
(SELECT MAX(test_date) FROM nextDateCTE) AS [最后一天],
DATEDIFF (
dd,
(SELECT MIN(test_date) FROM prevDateCTE),
(SELECT MAX(test_date) FROM nextDateCTE)
) + 1 AS [存在的連續日期]

轉載URL:http://hi.baidu.com/wangzhiqing999/item/2abb8bf3aeeb4a7d3c198b46


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM