2016-06-03 3 views
-1

То, что я пытаюсь достичь, - это подсчет попыток входа пользователя на основе значения LoginAttempts и LastLoginDate. Например, мне нужно запросить LastLoginDate в течение 30 дней с 2 ​​Loginattempts.Как подсчитать столбцы даты на основе другой столбца даты?

sampledb

результат должен быть: Output

Что я имею this..I создал временную таблицу, чтобы вытащить информацию и и это, похоже, не рассчитывает правильно. Вот где я застрял. Любая помощь будет оценена!

sample database

+1

Какие результаты вы получаете вместо этого? – Sev09

+0

Я смущен вашей моделью данных. Для меня это выглядит так: первые 4 столбца взяты из таблицы 'User', а последний столбец из связанной таблицы' Login' (?) С соединением между ними, но ваш запрос просто показывает таблицу 'User', а' Столбец LoginAttempts. Или это столбец 'LoginDateUTC'? Но отдельные записи журналов логинов не будут в главной таблице «Пользователь», поэтому я смущен. – Andreas

+0

Ваш пример показывает 4 'LoginAttempts' для' JON', так почему вы ожидаете подсчет '2'? Или вы имели в виду только подсчет * попыток * в течение 30 дней? Если да, не считаете ли вы, что предложение WHERE должно быть 'LoginDateUTC> = ...', а не 'LastLoginDateUTC> = ...'? – Andreas

ответ

0

Не уверен, если я понимаю ваш запрос полностью, но вот что-то за пределами коробки. Удачи !:

select FirstName, StudentID, UserName, LastLoginDate, LoginAttempts, 
    RowNumber = row_number() over(partition by StudentID order by StudentID, LoginAttempts) 
    into #temp1 
    from user 
    where cast(LastLoginDate as date) >= getdate()- 30 
    --should return all rows of data for past 30 days. 
    --should also rank each loginAttempt by student 

    select * from #temp1 
    where RowNumber >= 3 
0

Это не ответ ... еще одно предложение.

Как я вижу, у вас есть студенты, и вам необходимо провести аудит попыток входа в систему.
Это для меня отношение друг к другу.
Таким образом, я бы сохранил таблицу 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 

Вы также можете создать представление на основе запроса для более легкого доступа.

Напоминаю, что это всего лишь предложение, как я это сделаю.

2

Неправильная страница GROUP BY. Он включает в себя LastLoginDateUTC. Следовательно, вы учитываете логины на дату, а не логины в течение 30 дней.

Drop LastLoginDateUTC из вашей группы GROUP BY и измените предложение SELECT, чтобы использовать max(LastLoginDateUTC) as LastLoginDateUTC. Это должно дать вам то, что вы хотите.

Смежные вопросы