我需要执行以下操作:
Year | Weekno | Weekrange | No_Users
-------+------------+---------------------+-------------
2018 | 29 | W 22/09 - 28/09 | 68,574
2018 | 28 | W 15/09 - 21/09 | 57,452
....
根据以下数据:
Login_time | User
--------------+------------------
2018-09-27 | alex9172
2018-09-26 | christinelane
2018-09-26 | alex9172
2018-09-26 | abcded
2018-09-25 | nqohs
2018-09-25 | abcded
2018-09-25 | alex9172
2018-09-25 | owscjwo91
....
所以想出了一年和一周的时间,我可以使用
group by datepart(week, Login_date), datepart(year, login_date)
但是在周末,我被困住了。
请帮助我,谢谢。
答案 0 :(得分:1)
请尝试以下查询:
select yr, wk, concat('W ',FORMAT(min(login_time), 'dd/MM', 'en-US' ),' - W ',FORMAT(max(login_time), 'dd/MM', 'en-US' )) as weekrange,
count(user) as totaluser
from
(
select year(Login_time) as yr,datepart(isowk, Login_time) as wk, Login_time,user
from tablename
)A
group by yr, wk
答案 1 :(得分:0)
嗨,经过一段时间的挣扎,我终于找到了解决方法:
SELECT
datepart(year, login_time) as year
,datepart(week, login_time) as weekno
,'W ' + format(DATEADD(DAY, 2 - DATEPART(WEEKDAY, login_time), login_time), 'dd'+'/'+'MM') + ' - ' + format(DATEADD(DAY, 8 - DATEPART(WEEKDAY, login_time), login_time), 'dd'+'/'+'MM') as weekrange
,COUNT(DISTINCT User) as No_Users
FROM mytable
GROUP BY datepart(year, login_time)
,datepart(week, login_time)
,'W ' + format(DATEADD(DAY, 2 - DATEPART(WEEKDAY, login_time), login_time), 'dd'+'/'+'MM') + ' - ' + format(DATEADD(DAY, 8 - DATEPART(WEEKDAY, login_time), login_time), 'dd'+'/'+'MM')
非常感谢Satyaprakash Samantaray:https://www.c-sharpcorner.com/blogs/get-week-start-date-week-end-date-using-sql-server
答案 2 :(得分:0)
我不能对性能做出任何保证,但我相信它每次都会给出正确的答案。
create table UserLogin ( [User] nvarchar(50),
Login_Time datetime2 )
insert into UserLogin ( [User], Login_Time ) values
( 'Bart', '2018-12-31T12:13:14.888' ),
( 'Mary', '2019-01-06T09:10:11.876' ),
( 'Fred', '2018-12-31T21:22:23.456' ),
( 'Fred', '2019-01-01T07:08:09.101' ),
( 'Fred', '2018-09-17T13:14:15.616' ),
( 'Wilma', '2018-09-23T11:12:13.141' ),
( 'Betty', '2018-11-11T14:41:14.444' )
;with
-- Using DATEPART(WEEK,... has a problem. When called on two dates
-- in the same week, it can give different results.
-- For example, 31-Dec-2018 and 01-Jan-2019 are in the same week,
-- but DATEPART(WEEK,... returns 53 and 1.
-- To solve this, we'll use ISO_WEEK instead.
-- ISO defines week 1 of a year as the seven days starting on a Monday
-- that contain the first Thursday of the year.
-- This means that week 1 can begin in the previous year.
-- Calling DATEPART(ISO_WEEK,... on 31-Dec-2018 and 01-Jan-2019 both return 1.
U as
( select [User],
Login_Time,
DatePart(ISO_WEEK,Login_Time)as [Week],
Year(Login_Time)as [Year]
from UserLogin ),
-- For both 31-Dec-2018 and 01-Jan-2019, we want the
-- Year to be 2019 and the Week to be 1.
-- So when we have ISO week 1, and a date near the end of the year,
-- we want to use the following year.
V as
( select [User],
[Week],
case when [Week]=1 and Month(Login_Time)=12
then [Year]+1
else [Year]
end as [Year]
from U ),
-- Count the distinct users in each time period
A as
( select [Year],
[Week],
count(distinct [User])as No_Users
from V
group by [Year],[Week] ),
-- This is January 1st of year 0001, the earliest date that SQL Server
-- can handle. We'll be using it shortly.
Z as
( select cast('0001-01-01T00:00:00.000'as datetime2)as DayZero ),
-- To get the first day of the year,
-- add that many years, subtract 1, to 01-Jan-0001.
F as
( select No_Users,
DATEADD(year,[Year]-1,DayZero)as FirstDayOfYear,[Year],
[Week]
from A, Z ),
-- What day of the week is the first day of the year?
-- By counting the days from 01-Jan-0001 we bypass
-- any confusion caused by different values of @@DATEFIRST,
-- or negative numbers. Divide by 7 and keep the remainder.
-- The result is 0 for Monday, 1 for Tuesday and so on.
D as
( select No_Users,
FirstDayOfYear,
DATEDIFF(day,DayZero,FirstDayOfYear)%7 as DayOfWeekOfFirstDay,
[Year],
[Week]
from Z, F ),
-- Now we work out the date of the Monday of the week 1.
-- When the first day of the year is a Monday (0),
-- we just keep that day.
-- When it is Tuesday (1), we subtract 1 day.
-- For Wednesday(2), we subtract 2 days.
-- And for Thursday (3), we subtract 3 days.
-- If the first day of the year is Friday (4), we need to add 3 days.
-- For Saturday (5) we add 2 days,
-- and for Sunday (6) we add 1 day.
-- The expression ( 10 - X ) % 7 - 3
-- gives us the number of days to add.
T as
( select No_Users,
DayOfWeekOfFirstDay,
DATEADD(day,(10-DayOfWeekOfFirstDay)%7-3,FirstDayOfYear)
as MondayWeekOne,
[Year],
[Week] from D ),
-- That gives us the Monday of the first week of the year.
-- Now we need to find the Monday of the week we're looking for.
W as
( select No_Users,
DATEADD(day,7*([Week]-1),MondayWeekOne)as MondayOfWeek,
[Year],
[Week] from T ),
-- Given the Monday that begins that week,
-- find the Sunday that ends that week.
S as
( select No_Users,
MondayOfWeek,
DATEADD(day,6,MondayOfWeek)as SundayOfWeek,
[Year],
[Week] from W )
-- Format and sort to taste.
select [Year],
[Week],
'W ' + format(MondayOfWeek, 'dd/MM')
+ ' - '
+ format(SundayOfWeek, 'dd/MM') as WeekRange,
No_Users
from S
order by [Year],[Week]
结果是:
Year Week WeekRange No_Users
----------- ----------- --------------- --------
2018 38 W 17/09 - 23/09 2
2018 45 W 05/11 - 11/11 1
2019 1 W 31/12 - 06/01 3