我目前每天都有不同数量的用户登录。
我想添加另一列,以了解过去7天至少登录一次的用户数量。
;WITH cte (login_date, years, iso_week, months, emails) AS
(
SELECT
CAST(a.login_time AS Date),
DATEPART(YEAR, a.login_time),
DATEPART(ISO_WEEK, a.login_time),
DATEPART(MONTH, a.login_time),
COUNT(DISTINCT a.email) AS Total
FROM
database.log AS a WITH(NOLOCK)
GROUP BY
CAST(a.login_time AS Date),
DATEPART(YEAR, a.login_time),
DATEPART(ISO_WEEK, a.login_time),
DATEPART(MONTH, a.login_time)
)
现在,如果我尝试
SELECT
*,
SUM(emails) OVER (PARTITION BY years, iso_weeks
ORDER BY login_date
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS counts_week
FROM
cte
这基本上增加了每天登录一次化妆的时间,但这与我想要的相反。这不是7天不同电子邮件登录的总和,而是一周内登录的唯一电子邮件
因此,如果我以三封电子邮件为例,我应该在emails_week
列中包含以下内容
+------------+-------+----------+--------+--------+-------------+
| login_date | years | iso_week | months | emails | emails_week |
+------------+-------+----------+--------+--------+-------------+
| 2018-12-07 | 2018 | 49 | 12 | 2 | 2 |
| 2018-12-08 | 2018 | 49 | 12 | 2 | 2 |
| 2018-12-09 | 2018 | 49 | 12 | 1 | 2 |
| 2018-12-10 | 2018 | 50 | 12 | 1 | 3 |
| 2018-12-11 | 2018 | 50 | 12 | 3 | 3 |
| 2018-12-12 | 2018 | 50 | 12 | 1 | 3 |
+------------+-------+----------+--------+--------+-------------+
答案 0 :(得分:1)
肯定有一种更漂亮的方法可以执行此操作-但是-我已经编辑了SQL以根据ISO周编号检查每周。基本上,使用星期数来确定不同电子邮件计数的开始和结束日期。这个新版本使用多个CTE首先获取日期列表及其星期编号。第二个CTE(ldetails)在[login_time]上不再包含您的分组,然后我将其与星期数的结果一起加入。
设置
Declare @tbl Table
(
login_time Datetime,
email VarChar(50)
)
Insert Into @tbl Values
('2018-12-02','email@domain.com'),
('2018-12-02','emailyyyy@domain.com'),
('2018-12-07','emailxx@domain.com'),
('2018-12-07','emailzzz@domain.com'),
('2018-12-07','emailzzz@domain.com'),
('2018-11-07','email@domain.com'),
('2018-11-07','emailx@domain.com'),
('2018-12-01','email@domain.com'),
('2018-12-11','email@domain.com')
查询
;With ldates As
(
Select Cast(Login_time As Date) As Login_Date,Max(DATEPART(YEAR, login_time)) As [Year],Max(DATEPART(ISO_WEEK, login_time)) As [Week] From @tbl
Group By Login_time
),
ldetails As
(
SELECT
--CAST(a.login_time AS Date) As lTime,
DATEPART(YEAR, a.login_time) As [Year]
,DATEPART(ISO_WEEK, a.login_time) As [Week]
,DATEPART(MONTH, a.login_time) As [Month]
,Count (Distinct email) As tot
,COUNT(DISTINCT (Case When login_time Between DateAdd(DD,-7,GETDATE()) And GetDate() Then email Else Null End)) AS Total
,Count(Distinct
(Case When login_time Between
(DATEADD(DAY, (7 * (DATEPART(ISO_WEEK, login_time)-1)), Cast(DATEPART(YEAR, login_time) As Char(4)) + '-01-01' )) And
(DATEADD(DAY, (7 * (DATEPART(ISO_WEEK, login_time)-1)) +7, Cast(DATEPART(YEAR, login_time) As Char(4)) + '-01-01' ))
Then email Else Null End
)) AS Totalyy
FROM @tbl AS a
GROUP BY
--CAST(a.login_time AS Date),
DATEPART(YEAR, a.login_time),
DATEPART(ISO_WEEK, a.login_time),
DATEPART(MONTH, a.login_time)
)
Select lDates.login_Date,ldetails.[Year],ldetails.[Week],ldetails.[Month],ldetails.tot,ldetails.Total,ldetails.Totalyy From ldetails
Inner JOIN
lDates On ldetails.[Week] = lDates.[Week] And ldetails.[Year] = lDates.[Year]
结果
login_Date Year Week Month tot Total Totalyy
2018-11-07 2018 45 11 2 0 2
2018-12-01 2018 48 12 2 0 2
2018-12-02 2018 48 12 2 0 2
2018-12-07 2018 49 12 2 2 2
2018-12-11 2018 50 12 1 1 1
答案 1 :(得分:-2)
您是否尝试过使用COUNT(DISTINCT ...)?