SQL:登录和注销表以及插入注销
Posted
技术标签:
【中文标题】SQL:登录和注销表以及插入注销【英文标题】:SQL: Login and Logout table and inserting logouts 【发布时间】:2018-05-22 15:41:36 【问题描述】:所以,我们有一个表 lds_user_log,它记录了我们 CSR 当天的登录和注销。这很好,我有一个脚本,旨在为我们的指标提取他们每天登录的分钟数:
IF OBJECT_ID('tempdb..#tmpLogins1') IS NOT NULL DROP TABLE #tmpLogins1
IF OBJECT_ID('tempdb..#tmpLogins') IS NOT NULL DROP TABLE #tmpLogins
SELECT T1.[user],
T1.[user_group],
T1.event_Date,
isnull( MIN(T2.event_date),'2018-05-21 17:00:0') AS Date2,
DATEDIFF(minute, T1.event_Date, isnull( MIN(T2.event_date),'2018-05-21 17:00:0')) AS minDiff
INTO #tmpLogins1
FROM [LEADS].[dbo].[lds_User_log] T1
LEFT JOIN [LEADS].[dbo].[lds_User_log] T2
ON T1.[user_group]= T2.[user_group]
AND T2.event_Date > T1.event_Date
and t1.[user]=t2.[user]
where t1.event_date>= @startdate
--AND t2.event_date <= '2018-05-21 23:00:01'
GROUP BY T1.[user], T1.[user_group], T1.event_Date;
select distinct [user],
user_group,
sum(minDiff) over (partition by [user]) as totMins
INTO #tmpLogins
from #tmpLogins1
这会返回:
这也很好,但是我们的一些 CSR 不会从他们的系统中注销,这会在 LOGOUT 事件中留下 NULL,其中(因为我不知道另一种方法)迫使我使用 ISNULL从上面,假设他们在下午 5 点离开。
有没有一种方法,即使使用临时表,我也可以将同一天有 LOGIN 但没有 LOGOUT 的用户强制放入 LOGOUT 临时表中?这是因为我们希望能够运行此报告一整周,并且一些代表将回家并且永远不会注销(只需关闭他们的浏览器)然后在第二天重新登录,永远不会产生 LOGOUT 事件。但我们需要它
FRI - 1st LOGIN | LAST LOGOUT
MON - 1st LOGIN | LAST LOGOUT
TUE - 1st LOGIN | LAST LOGOUT
WED - 1st LOGIN | LAST LOGOUT
THU - 1st LOGIN | LAST LOGOUT
以及它们之间的 MINUTES,再次假设他们在特定日期的下午 5 点 (1700) 离开,如果他们没有生成 LOGOUT 事件。
当我从昨天的特定用户的表中提取所有数据时。
select *
from LEADS.[dbo].[lds_User_log]
where [USER] = 'gunnr' AND event_date > '2018-05-21 00:00:01'
它确实列出了:
这是整个字段列表:
SELECT [user_log_id]
,[user]
,[event]
,[campaign_id]
,[event_date]
,[event_epoch]
,[user_group]
,[session_id]
,[server_ip]
,[extension]
,[computer_ip]
,[browser]
,[data]
,[phone_login]
,[server_phone]
,[phone_ip]
,[webserver]
,[login_url]
,[browser_width]
,[browser_height]
FROM [LEADS].[dbo].[lds_User_log]
【问题讨论】:
他们可以在中午注销吗?给予:In @ 9am, Out @ 12pm, In @ 1pm, Out @ NULL
? (即使不频繁,它仍然需要处理......) 或者,如果他们上午 9 点登录,下午 12 点关闭浏览器,下午 1 点再次登录,下午 5 点关闭浏览器,如何你能说下午 1 点是登录而不是注销吗?
如果他们从未注销过,他们如何在第二天重新登录?同一用户可以登录两次吗?您可以为应用/环境中的不活动设置超时吗?
创建一个在一天结束时运行的作业,自动注销那些在当天登录但尚未注销的人 - 这也将迫使他们在第二天重新登录给你更好的数据
@MatBailie - 是的,他们可以,事实上他们应该 - 在上午 8:30 登录,在 1200 注销,在 1230 登录,在 1700 注销。
@dfundako 因为我们的系统真的很奇怪....不是我能影响的东西。
【参考方案1】:
SELECT
[user_group],
[user],
pivots.event_date,
MIN(pivots.login) AS first_login,
CASE
WHEN MAX(pivots.login) < MAX(pivots.logout)
THEN MAX(pivots.logout)
ELSE DATEADD(HOUR, 17, pivots.event_date)
END
AS last_logout
FROM
[LEADS].[dbo].[lds_User_log]
CROSS APPLY
(
SELECT CAST(CAST(event_date AS DATE) AS DATETIME) AS event_date,
CASE WHEN event = 'LOGIN' THEN event_date END AS login,
CASE WHEN event = 'LOGOUT' THEN event_date END AS logout
)
pivots
GROUP BY
[user_group],
[user],
pivots.event_date
或者,更灵活...
WITH
augmented
AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY event_date_only,
[user_group],
[user]
ORDER BY event_date DESC
)
AS reverse_seq
FROM
[LEADS].[dbo].[lds_User_log]
CROSS APPLY
(
SELECT CAST(CAST(event_date AS DATE) AS DATETIME)
)
AS date_only(event_date_only)
)
SELECT
[user_group],
[user],
event_date_only,
MIN(login) AS first_login,
MAX(logout) AS last_logout
FROM
augmented
CROSS APPLY
(
SELECT CASE WHEN event = 'LOGIN' THEN event_date END AS login,
CASE WHEN event = 'LOGOUT' THEN event_date END AS logout
UNION ALL
-- Creates a "fake" logout if the last event of the day is a login
SELECT NULL,
DATEADD(HOUR, 17, event_date_only)
WHERE reverse_seq = 1
AND event = 'LOGIN'
)
AS pivots
GROUP BY
[user_group],
[user],
event_date_only
【讨论】:
抱歉,我会更新,有 [event] 表明登录和注销。我会为它更新主帖。 另外,我得到:Msg 9810,Level 16,State 1,Line 1 日期函数 dateadd 不支持 datepart 小时数据类型 date。 @dragos_kai : 你想要第一次登录和最后一次注销之间的总时间,还是累计注销-previous_login (8:30 到 12:00 加上 12:30 到 17:00 是8 小时,还是 8.5 小时?) @dragos_kai : 如果一天中的第一个事件是注销,您希望如何处理? 最早的 LOGIN 事件和最新的 LOGOUT 事件之间的累积时间(如果当天没有 LOGOUT,则为 1700)另外,我认为他们在物理上不可能让它成为注销作为他们的第一个操作。我已经对此进行了审查,但它一直没有发生(至少 3 年,这是我可以访问的最新版本。以上是关于SQL:登录和注销表以及插入注销的主要内容,如果未能解决你的问题,请参考以下文章
简单两步快速实现shiro的配置和使用,包含登录验证角色验证权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)