SQL Server 2016:查询最近WebSession为76天前的UserId问题
解决SQL查询报错及需求实现方案
首先说下你遇到的报错原因:SQL的执行顺序是先处理WHERE子句,再处理SELECT子句,所以你在WHERE里引用SELECT中定义的别名LastAccess时,数据库还没识别到这个别名,自然会报错“Invalid column name 'LastAccess'”。
针对你的需求——筛选出最近一次WebSession距今76天的所有UserId,这里给你两种可行的写法:
方法一:GROUP BY + HAVING(最直接的方式)
因为我们需要先按UserId分组,拿到每个用户的最后登录时间,再筛选时间条件。HAVING子句是在分组聚合之后执行的,可以直接引用聚合函数的结果:
SELECT UserId, MAX(Created) AS LastAccess FROM WebSessions GROUP BY UserId HAVING DATEDIFF(day, MAX(Created), GETDATE()) = 76;
如果你的实际需求是“最近一次登录距今超过76天”,只需要把=改成>就行。
方法二:子查询先获取最后登录记录
先通过子查询得到每个用户的最近登录时间,再在外层筛选符合条件的用户,这种写法逻辑更清晰,也方便后续关联Users表获取更多用户信息:
SELECT ws.UserId, ws.LastAccess FROM ( -- 先拿到每个用户的最后登录时间 SELECT UserId, MAX(Created) AS LastAccess FROM WebSessions GROUP BY UserId ) AS ws WHERE DATEDIFF(day, ws.LastAccess, GETDATE()) = 76;
如果需要关联Users表(比如要获取用户名等其他字段),可以这么写:
SELECT u.UserId, u.Username, ws.LastAccess FROM Users u JOIN ( SELECT UserId, MAX(Created) AS LastAccess FROM WebSessions GROUP BY UserId HAVING DATEDIFF(day, MAX(Created), GETDATE()) = 76 ) AS ws ON u.UserId = ws.UserId;
补充说明下:DATEDIFF(day, start, end)会计算两个日期之间的天数差,比如如果某用户的最后登录时间是76天前,那么这个函数返回的结果就是76,刚好匹配你的需求。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

