工作中遇到的一道SQL应用题
登录日志表
CREATE TABLE [dbo].[LoginLog]
(
[Seq] [int] NOT NULL IDENTITY(1, 1), --Seq
[UserId] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL, --用户名
[LoginTime] [datetime] NULL, --登录时间
[SuccessFlg] [bit] NULL, --登录是否成功
) ON [PRIMARY]
GO
需求:返回用户是否能继续登录
登录规则:如果用户1小时内登录三次错误,则锁定1天内无法登录
实现SQL
SELECT CASE WHEN COUNT(1) = 3 THEN 1 ELSE 0 END LockFlg FROM ( SELECT TOP 3 l.* FROM LoginLog l with(nolock) INNER JOIN ( SELECT TOP 1 Seq,SuccessFlg,LoginTime,UserId FROM dbo.LoginLog with(nolock) WHERE UserId='sdf333' AND LoginTime >= DATEADD(DAY,-1,GETDATE()) ORDER BY Seq DESC ) lastLog ON l.Seq <= lastLog.Seq AND l.UserId = lastLog.UserId WHERE DATEDIFF(HOUR, l.LoginTime,lastLog.LoginTime) < 1 ORDER BY l.Seq desc ) AS t WHERE t.successflg = 0
公司的一位新人对SQL挺有兴趣的。就让他试试。给到的SQL:
SELECT COUNT(1) LockFlg FROM ( SELECT CASE WHEN COUNT(*)=3 THEN 1 ELSE 0 END AS near3, CASE WHEN DATEDIFF(HOUR,MIN(t.LoginTime),MAX(t.LoginTime))<1 THEN 1 ELSE 0 END AS inonehour, CASE WHEN SUM(CAST(t.SuccessFlg AS INT) )=0 THEN 1 ELSE 0 END AS wrongtimes, CASE WHEN DATEDIFF(HOUR,MAX(t.LoginTime),GETDATE())<24 THEN 1 ELSE 0 END AS inoneday FROM ( SELECT TOP 3 * FROM dbo.LoginLog WHERE UserId='sdf333' ORDER BY logintime DESC )t )tt WHERE near3=1 AND inonehour=1 AND wrongtimes=1 AND inoneday=1
这位同学的思路更简单直接,感觉我已经老了~~~