이 답변이 아닙니다 ... 더 많은 제안.
본인은 학생이 있으며 로그인 시도를 감사해야합니다.
나를 위해 이것은 일대 다 많은 관계입니다.
그래서 나는 Student 테이블을 유지할 것이고, 어떤 로그인 관련 데이터로부터도 제거 될 것이다.
이렇게하면 동일한 데이터 (이름, 사용자 이름 등)를 반복 사용하지 않기 위해 행을 줄이고 저장 공간을 절약하면서 Student
테이블을 단순화 할 수 있습니다.
데이터가 StudentLoginAttempts
에있을 것이라고, 뭔가 같은 :
Create Table StudentLoginAttempts (
Id int not null identity(1,1),
StudentId int not null,
LoginDate datetime not null,
Successful bit not null,
Constraint PK_StudentLoginAttempts Primary Key Clustered (Id),
Constraint FK_StudentLoginAttempts_Student Foreign Key (StudentId) References Student(StudentId)
)
go
Create Index IX_StudentLoginAttempts_StudentId On StudentLoginAttempts(StudentId)
go
Create Index IX_StudentLoginAttempts_LoginDate On StudentLoginAttempts(LoginDate)
go
그래서 일이 더 명확 할 수 있고 당신은 더 많은 정보를 가질 수 있습니다.
Create Table #Student (
StudentId int not null identity(1,1),
Username varchar(50) not null,
FirstName varchar(50) not null
)
Create Table #StudentLoginAttempts (
Id int not null identity(1,1),
StudentId int not null,
LoginDate datetime not null,
Successful bit not null
)
insert into #Student values
('Student001', 'JON'),
('Student002', 'STEVE')
insert into #StudentLoginAttempts values
(1, '2016-01-01 09:12', 0),
(1, '2016-02-01 09:12', 0),
(1, '2016-03-01 09:12', 1),
(2, '2016-03-02 10:12', 0),
(2, '2016-04-02 10:12', 1),
(2, '2016-05-02 10:12', 0)
;with TotalAttemptsCte as (
select StudentId, TotalLoginAttempts = count(*) from #StudentLoginAttempts group by StudentId
),
FailedCte as (
select StudentId, FailedLogins = count(*) from #StudentLoginAttempts where (Successful = 0) group by StudentId
),
SuccessfulCte as (
select StudentId, SuccessfulLogins = count(*) from #StudentLoginAttempts where (Successful = 1) group by StudentId
),
LastSuccessFulDateCte as (
select StudentId, max(LoginDate) as LastSuccessfulLoginDate
from
#StudentLoginAttempts
where
(Successful = 1)
group by StudentId
)
select
a.*, b.TotalLoginAttempts, c.FailedLogins, d.SuccessfulLogins, e.LastSuccessfulLoginDate
from
#Student a
left join TotalAttemptsCte b on (a.StudentId = b.StudentId)
left join FailedCte c on (a.StudentId = c.StudentId)
left join SuccessfulCte d on (a.StudentId = d.StudentId)
left join LastSuccessFulDateCte e on (a.StudentId = e.StudentId)
Drop Table #StudentLoginAttempts
Drop Table #Student
또한 더 쉽게 액세스 할 수 있도록 쿼리를 기반으로 뷰를 만들 수 있습니다
는 울부 짖는 소리의 예를 생각해보십시오.
나는 이것이 단지 제안 일 뿐이라는 것을 상기시켜드립니다.
대신 결과가 어떻습니까? – Sev09
귀하의 데이터 모델에 대해 혼란스러워합니다. 내게는 처음 4 컬럼이'User' 테이블에 있고 마지막 컬럼이 관련'Login' (?) 테이블에 있고, 그 사이에 조인이있는 것처럼 보입니다. 그러나 쿼리는'User' 테이블과' LoginAttempts' 열에 있습니다. 아니면'LoginDateUTC' 칼럼입니까? 하지만 로그인의 개별 로그 레코드는 주 User 테이블에 없으므로 혼란 스럽습니다. – Andreas
당신의 예제는'JON'에 대한 4 개의'LoginAttempts'를 보여줍니다. 왜'2 '의 수를 기대합니까? 또는 30 일 이내에 * 시도 수만 계산하는 것을 의미합니까? 그렇다면'WHERE' 절이'LastLoginDateUTC> = ...'가 아니라'LoginDateUTC> = ...'이어야한다고 생각하지 않습니까? – Andreas