事情的原因
我的解
SELECT ROUND(
(SELECT CONVERT(DECIMAL(18,2),COUNT(DISTINCT player_id)) FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY player_id ORDER BY event_date) AS num,event_date,player_id FROM Activity
) AS a LEFT JOIN Activity b ON a.player_id=b.player_id
WHERE a.num=1 AND DATEDIFF(DAY,a.event_date,b.event_date)=1)
/
(SELECT CONVERT(DECIMAL(18,2),COUNT(DISTINCT player_id)) FROM Activity)
,2
)
最优解
SELECT
ROUND(sum(
case
when datediff(day, b.event_date, a.event_date) = 1 then 1.00
else 0.00
end) / COUNT(DISTINCT a.player_id), 2) AS fraction
FROM
Activity a
,
(
select player_id, min(event_date) event_date
from activity
group by player_id
) b
WHERE
a.player_id = b.player_id
起初我也打算用联表的方式给它解决的,没想到,做的时候感觉遇到了点麻烦,后来觉得还是太麻烦了,所以还是选择了用分组排序的方式去做,主打一个简单快速,我看了写最优解的兄弟,他也写好不少草稿,sum(case when … then 1.00 else 0.00 end)这个统计的方式出来了好几次了,可以记一下,会用的上
处理日期相关的函数在实际开发过程中用的还是挺频繁的需要完全掌握
--GETDATE()返回当前时间
SELECT GETDATE()
--返回日期指定部分 日期/时间
--年度 Year、YYYY、YY
--月份 Month、MM、M
--日期 Day、DD、D
--周 Week、WK、WW
--每周星期几 WeekDay、DW
--季度 Quarter、QQ、Q
--一年中第几天 DayOfYear、DY、Y
--小时 Hour、HH
--分钟 Minute、MI、N
--秒 Second、SS、SS
--毫秒 MillSecond、MS
SELECT DATEPART(DY,GETDATE())
--在日期/时间的指定部分上加上一个时间
SELECT DATEADD(DAY,1,GETDATE())
--调整日期格式
--101 美国 — 月/日/年
--102 ANSI — 日/月/年
--103 英国/法国 — 日/月/年
--104 德国 — 日.月.年
--105 意大利 — 日/月/年
--112 美国 — 月-日-年
--120 ISO — 年-月-日 HH:mi:ss
SELECT CONVERT(VARCHAR,GETDATE(),120)
--FORMAT支持自定义输出日期时间,但是需SQL Server>=2012版本
SELECT FORMAT(GETDATE(),'yyyy-MM-dd HH:mm:ss')
--CAST将表达式转换为指定的数据类型
SELECT CAST(GETDATE() AS DATE)
--获取指定时间的年月日
SELECT YEAR(GETDATE()),MONTH(GETDATE()),DAY(GETDATE())