2016-06-03 4 views
-1

내가 얻으려고하는 것은 LoginAttempts 값과 LastLoginDate를 기반으로 사용자의 로그인 시도를 계산하는 것입니다. 예를 들어, 로그인 시도 수를 2로 설정하여 30 일 이내에 LastLoginDate를 쿼리해야합니다.다른 날짜 열을 기준으로 날짜 열을 계산하려면 어떻게합니까?

sampledb

결과는 다음과 같아야합니다 Output

은 내가해야하는 정보를 뽑아 this..I 만든 임시 테이블이며, 그것은 제대로 계산하지 않는 것. 내가 붙어있는 곳이 여기에있다. 어떤 도움도 감사하겠다 !! 내가 완전히 귀하의 요청을 이해하지만, 여기에 상자 밖에서 뭔가 있는지 확실하지

sample database

+1

대신 결과가 어떻습니까? – Sev09

+0

귀하의 데이터 모델에 대해 혼란스러워합니다. 내게는 처음 4 컬럼이'User' 테이블에 있고 마지막 컬럼이 관련'Login' (?) 테이블에 있고, 그 사이에 조인이있는 것처럼 보입니다. 그러나 쿼리는'User' 테이블과' LoginAttempts' 열에 있습니다. 아니면'LoginDateUTC' 칼럼입니까? 하지만 로그인의 개별 로그 레코드는 주 User 테이블에 없으므로 혼란 스럽습니다. – Andreas

+0

당신의 예제는'JON'에 대한 4 개의'LoginAttempts'를 보여줍니다. 왜'2 '의 수를 기대합니까? 또는 30 일 이내에 * 시도 수만 계산하는 것을 의미합니까? 그렇다면'WHERE' 절이'LastLoginDateUTC> = ...'가 아니라'LoginDateUTC> = ...'이어야한다고 생각하지 않습니까? – 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 일마다 로그인하지 않고 날짜별로 로그인을 계산합니다.

GROUP BY에서 LastLoginDateUTC를 삭제하고 max(LastLoginDateUTC) as LastLoginDateUTC을 사용하도록 SELECT 절을 변경하십시오. 그게 네가 원하는 걸 줄거야.

관련 문제