sql server datetime每小时间隔

时间:2015-03-03 06:16:33

标签: sql sql-server

我有一张桌子" logintracking"和领域是"尝试结果"和"尝试"。

attemptdate             attemptresult
2007-12-18 14:33:24.000 LOGOUT
2007-12-18 14:33:38.000 SUCCESS
2007-12-18 14:35:36.000 LOGOUT
2007-12-18 14:46:50.000 SUCCESS
2007-12-18 16:52:48.000 TIMEOUT
2007-12-18 16:57:33.000 SUCCESS
2007-12-18 18:49:49.000 TIMEOUT
2008-01-10 13:02:32.000 SUCCESS

等等

我希望结果为:

DATE                    COUNT(login)
2007-12-18 14:00:00.000 1
2007-12-18 15:00:00.000 0
2007-12-18 16:00:00.000 0
2007-12-18 17:00:00.000 0
2007-12-18 18:00:00.000 0   
2007-12-18 19:00:00.000 0
2007-12-18 20:00:00.000 0
2008-01-10 01:00:00.000 0

即。每小时从最小的调试开始直到最大的调度 并相应地计算特定时间的登录和注销。 请帮忙

3 个答案:

答案 0 :(得分:0)

在不知道如何计算登录次数的情况下,以下是我的建议:

我们的想法是在LoginTracking中生成所有日期的每小时间隔。然后LEFT JOIN进入LoginTracking以获得结果:

CREATE TABLE LoginTracking(
    AttemptDate     DATETIME,
    AttemptResult   VARCHAR(10)
)

INSERT INTO LoginTracking VALUES
('2007-12-18 14:33:24.000', 'LOGOUT'),
('2007-12-18 14:33:38.000', 'SUCCESS'),
('2007-12-18 14:35:36.000', 'LOGOUT'),
('2007-12-18 14:46:50.000', 'SUCCESS'),
('2007-12-18 16:52:48.000', 'TIMEOUT'),
('2007-12-18 16:57:33.000', 'SUCCESS'),
('2007-12-18 18:49:49.000', 'TIMEOUT'),
('2008-01-10 13:02:32.000', 'SUCCESS');

;WITH CteCross AS(
    SELECT
        lt.AttemptDate,
        N = x.N - 1
    FROM(
        SELECT DISTINCT 
            CAST(AttemptDate AS DATE) AS AttemptDate
        FROM LoginTracking
    )lt
    CROSS JOIN(
        SELECT 1  UNION ALL SELECT 2  UNION ALL SELECT 3  UNION ALL SELECT 4  UNION ALL SELECT 5 UNION ALL 
        SELECT 6  UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL SELECT 9  UNION ALL SELECT 10 UNION ALL 
        SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL
        SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL
        SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23 UNION ALL SELECT 24 
    )x(N)
)
SELECT 
    AttemptDate = DATEADD(HOUR, cc.N, CAST(cc.AttemptDate AS DATETIME)),
    LoginCount = SUM(CASE WHEN lt.AttemptResult = 'SUCCESS' THEN 1 ELSE 0 END)
FROM CteCross cc
LEFT JOIN LoginTracking lt
    ON CAST(lt.AttemptDate AS DATE) = cc.AttemptDate
    AND DATEPART(HOUR, lt.AttemptDate) = cc.N
GROUP BY cc.AttemptDate, cc.N
ORDER BY AttemptDate


DROP TABLE LoginTracking

答案 1 :(得分:0)

尝试结果不是那么清楚。你应该解释为什么在14号logincount = 1和16号为什么它是0。

试试这个,

DECLARE  @LoginTracking TABLE(
    AttemptDate     DATETIME,
    AttemptResult   VARCHAR(10)
)

INSERT INTO @LoginTracking VALUES
('2007-12-18 14:33:24.000', 'LOGOUT'),
('2007-12-18 14:33:38.000', 'SUCCESS'),
('2007-12-18 14:35:36.000', 'LOGOUT'),
('2007-12-18 14:46:50.000', 'SUCCESS'),
('2007-12-18 16:52:48.000', 'TIMEOUT'),
('2007-12-18 16:57:33.000', 'SUCCESS'),
('2007-12-18 18:49:49.000', 'TIMEOUT'),
('2008-01-10 13:02:32.000', 'SUCCESS');

DECLARE @MinDate DateTime=
(SELECT DATEADD(hour,DATEDIFF(hour, 0,min(AttemptDate)), 0) FROM @LoginTracking)
DECLARE @MaxDate DateTime=
(SELECT DATEADD(hour,DATEDIFF(hour, 0,max(AttemptDate)), 0) FROM @LoginTracking)



;WITH CTE
AS (
    SELECT @MinDate [DATE]

    UNION ALL

    SELECT DATEADD(hour, 1, [date])
    FROM cte
    WHERE [date] < @MaxDate
    )
SELECT [DATE]
    ,isnull((
            SELECT TOP 1 1
            FROM @LoginTracking lt
            WHERE DATEADD(hour, DATEDIFF(hour, 0, AttemptDate), 0) = [Date]
                AND (
                    EXISTS (
                        SELECT AttemptResult
                        FROM @LoginTracking lt
                        WHERE DATEADD(hour, DATEDIFF(hour, 0, AttemptDate), 0) = [Date]
                            AND lt.AttemptResult = 'LOGOUT'
                        )
                    AND EXISTS (
                        SELECT AttemptResult
                        FROM @LoginTracking lt
                        WHERE DATEADD(hour, DATEDIFF(hour, 0, AttemptDate), 0) = [Date]
                            AND lt.AttemptResult = 'SUCCESS'
                        )
                    )
            ), 0)
FROM cte
OPTION (MAXRECURSION 0)

答案 2 :(得分:0)

SELECT  
case  
when TAB_1.a is NULL then TAB_2.a 
else TAB_1.a
END
"ATTEMPT DATE",
case 
when TAB_1.LOGIN  IS NULL  then 0
else TAB_1.LOGIN
END
"LOGIN",
case 
when TAB_2.LOGOUT  IS NULL  then 0
else TAB_2.LOGOUT
END
"LOGOUT"

FROM  
    (SELECT dateadd(hour,DATEDIFF(HOUR, 0, attemptdate),0) as a ,
COUNT(attemptresult) as LOGIN
    FROM logintracking
    WHERE attemptresult='LOGIN'
     group by  dateadd(hour,DATEDIFF(HOUR, 0, attemptdate),0)
     ) AS TAB_1
FULL JOIN
    (SELECT dateadd(hour,DATEDIFF(HOUR, 0, attemptdate),0) as a,
COUNT(attemptresult) as LOGOUT
    FROM logintracking
    WHERE attemptresult='LOGOUT' 
     group by  dateadd(hour,DATEDIFF(HOUR, 0, attemptdate),0) ) AS TAB_2
on TAB_1.a=TAB_2.a order by TAB_1.a

我用它来显示与尝试日期相对应的所有登录和注销。 但我想显示我的登录和注销都将是&#39; 0&#39;。和每小时显示的尝试次数