表結構如下:
每個用戶每天只能簽到一次
現在前面的需求是判斷某個用戶在某天是否是連續簽到,使用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