Это не ответ ... еще одно предложение.
Как я вижу, у вас есть студенты, и вам необходимо провести аудит попыток входа в систему.
Это для меня отношение друг к другу.
Таким образом, я бы сохранил таблицу 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'? Но отдельные записи журналов логинов не будут в главной таблице «Пользователь», поэтому я смущен. – Andreas
Ваш пример показывает 4 'LoginAttempts' для' JON', так почему вы ожидаете подсчет '2'? Или вы имели в виду только подсчет * попыток * в течение 30 дней? Если да, не считаете ли вы, что предложение WHERE должно быть 'LoginDateUTC> = ...', а не 'LastLoginDateUTC> = ...'? – Andreas