SQL 服务器中日期的第一个和最后一个记录
First and last record of a date in SQL Server
我想生成一个用户登录报告,其中我想向用户显示一个月中每一天的首次登录时间和最后一次注销时间。 UserLoginSession的table如下
UserLoginSessionId
UserId
LoginDate
LogoutDate
1310582
59
2021-04-30 15:49:54.997
2021-04-30 17:31:18.833
1310579
59
2021-04-30 14:53:51.460
NULL
1310575
59
2021-04-30 14:39:45.937
2021-04-30 14:52:23.150
1310569
59
2021-04-30 13:49:36.137
NULL
1300484
59
2021-04-28 15:17:48.837
NULL
1300478
59
2021-04-28 12:17:50.200
NULL
1300466
59
2021-04-28 04:23:48.697
2021-04-28 07:45:11.937
1299527
2466
2021-04-18 06:07:51.070
NULL
1299489
2466
2021-04-17 06:57:01.860
2021-04-17 06:57:28.260
1299449
2466
2021-04-16 10:16:54.730
NULL
1299442
2466
2021-04-16 10:08:30.187
2021-04-16 10:36:05.963
1299422
2466
2021-04-16 07:30:32.990
2021-04-16 10:15:25.777
输出报告应如下所示,如果注销日期为空,则应采用当天的结束时间
UserId
LoginDate
LogoutDate
59
2021-04-30 13:49:36.137
2021-04-30 17:31:18.833
59
2021-04-28 04:23:48.697
2021-04-28 23:59:59.000
2466
2021-04-18 06:07:51.070
2021-04-18 23:59:59.000
2466
2021-04-17 06:57:01.860
2021-04-17 06:57:28.260
2466
2021-04-16 07:30:32.990
2021-04-16 23:59:59.000
我试过下面的查询,但它在不同的行中给我输出。
select UserId, case when rn1 = 1 then LoginDate end as [LoginDate], case when rn2 = 1 then LogoutDate end as [LogoutDate]
from (
select
row_number() over (partition by U.UserId, convert(date,s.LoginDate) order by s.LoginDate) as rn1,
row_number() over (partition by U.UserId, convert(date,s.LogoutDate) order by s.LogoutDate desc) as rn2,
S.*
from UserLoginSession S
where S.CreatedAt between @StartDate and @EndDate
) as SubQueryTable
where rn1 = 1 or rn2 = 1
我无法在查询中将这两条记录放在一行中。如何修改我的查询以获得所需的结果?
使用 MIN 和 MAX 并在 LogoutDate 为 NULL 时进行修改:
SELECT UserId, CONVERT(date, LoginDate), MIN(LoginDate), ISNULL(MAX(LogoutDate), DATEADD(MS, -2, CONVERT(DATETIME,DATEADD(D, 1, CONVERT(date, LoginDate)))))
FROM UserLoginSession
GROUP BY UserId,CONVERT(date, LoginDate)
ORDER BY UserId,CONVERT(date, LoginDate)
我想生成一个用户登录报告,其中我想向用户显示一个月中每一天的首次登录时间和最后一次注销时间。 UserLoginSession的table如下
UserLoginSessionId | UserId | LoginDate | LogoutDate |
---|---|---|---|
1310582 | 59 | 2021-04-30 15:49:54.997 | 2021-04-30 17:31:18.833 |
1310579 | 59 | 2021-04-30 14:53:51.460 | NULL |
1310575 | 59 | 2021-04-30 14:39:45.937 | 2021-04-30 14:52:23.150 |
1310569 | 59 | 2021-04-30 13:49:36.137 | NULL |
1300484 | 59 | 2021-04-28 15:17:48.837 | NULL |
1300478 | 59 | 2021-04-28 12:17:50.200 | NULL |
1300466 | 59 | 2021-04-28 04:23:48.697 | 2021-04-28 07:45:11.937 |
1299527 | 2466 | 2021-04-18 06:07:51.070 | NULL |
1299489 | 2466 | 2021-04-17 06:57:01.860 | 2021-04-17 06:57:28.260 |
1299449 | 2466 | 2021-04-16 10:16:54.730 | NULL |
1299442 | 2466 | 2021-04-16 10:08:30.187 | 2021-04-16 10:36:05.963 |
1299422 | 2466 | 2021-04-16 07:30:32.990 | 2021-04-16 10:15:25.777 |
输出报告应如下所示,如果注销日期为空,则应采用当天的结束时间
UserId | LoginDate | LogoutDate |
---|---|---|
59 | 2021-04-30 13:49:36.137 | 2021-04-30 17:31:18.833 |
59 | 2021-04-28 04:23:48.697 | 2021-04-28 23:59:59.000 |
2466 | 2021-04-18 06:07:51.070 | 2021-04-18 23:59:59.000 |
2466 | 2021-04-17 06:57:01.860 | 2021-04-17 06:57:28.260 |
2466 | 2021-04-16 07:30:32.990 | 2021-04-16 23:59:59.000 |
我试过下面的查询,但它在不同的行中给我输出。
select UserId, case when rn1 = 1 then LoginDate end as [LoginDate], case when rn2 = 1 then LogoutDate end as [LogoutDate]
from (
select
row_number() over (partition by U.UserId, convert(date,s.LoginDate) order by s.LoginDate) as rn1,
row_number() over (partition by U.UserId, convert(date,s.LogoutDate) order by s.LogoutDate desc) as rn2,
S.*
from UserLoginSession S
where S.CreatedAt between @StartDate and @EndDate
) as SubQueryTable
where rn1 = 1 or rn2 = 1
我无法在查询中将这两条记录放在一行中。如何修改我的查询以获得所需的结果?
使用 MIN 和 MAX 并在 LogoutDate 为 NULL 时进行修改:
SELECT UserId, CONVERT(date, LoginDate), MIN(LoginDate), ISNULL(MAX(LogoutDate), DATEADD(MS, -2, CONVERT(DATETIME,DATEADD(D, 1, CONVERT(date, LoginDate)))))
FROM UserLoginSession
GROUP BY UserId,CONVERT(date, LoginDate)
ORDER BY UserId,CONVERT(date, LoginDate)