Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql server日期时间每小时间隔_Sql_Sql Server - Fatal编程技术网

sql server日期时间每小时间隔

sql server日期时间每小时间隔,sql,sql-server,Sql,Sql Server,我有一个表logintracking,字段是attemptresult和attemptdate 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-1

我有一个表logintracking,字段是attemptresult和attemptdate

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
i、 e.从最小尝试日期开始到最大尝试日期的每小时 以及在特定时间登录和注销的相应计数。
请在不知道如何计算登录计数的情况下提供帮助,以下是我的想法:

其思想是在LoginTracking中生成所有日期的每小时间隔。然后将其加入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

尝试结果不太清楚。您应该解释为什么在第14次登录时,logincount=1,为什么在第16次登录时,logincount为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)
我使用它来显示与尝试日期对应的所有登录和注销。
但我想显示我的登录和注销位置都是“0”。每小时显示一次attempdate

您能解释一下您是如何计算输出中的登录计数的吗??示例数据和预期输出没有意义。登录计算似乎是成功,然后是注销,但这就引出了一个问题-登录成功和注销之间是否存在任何关系?或者您是否只想知道成功后是否会在同一时间间隔内直接注销选择dateaddhour、DATEDIFFHOUR、0、attemptdate、0作为登录名,COUNTattemptresult作为登录名,其中attemptresult='LOGIN'组按dateaddhour、DATEDIFFHOUR、0、attemptdate、0I的登录名与上述查询中的登录名相同。注销也是一样。然后我使用了连接和子查询。你能解释一下N=x.N-1吗?请解释一下交叉连接内使用的选择交叉连接内的选择生成从1到24的行。我使用N-1,因为DATETIME的小时部分范围从0到23。为了理解,您可以在CTE之后对整个select进行注释。只需使用select*from CTE。我使用递归CTE生成最小日期和最大日期之间的日期范围。共有522行。
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