使用 COUNT(UserID) 时提取日期时间

Pulling Datetime when using COUNT(UserID)

我有表格Users

UserID     FirstName     LastName     Email
------     ---------     --------     -----
1          Fred          Smith        fs@abc.com
2          Bob           Hill         bh@abc.com
3          Jane          Doe          jd@abc.com

LoginSession

LoginSessionID     UserID     StartDate
--------------     ------     ---------
1                  1          2014-11-23 08:37:14.836
2                  1          2014-11-25 11:13:53.225
3                  2          2014-12-01 03:15:33.846
4                  1          2014-12-01 17:34:19.036
5                  3          2014-12-05 12:55:01.998
6                  1          2014-12-14 17:20:14.636
7                  3          2014-12-15 10:02:17.376

我想做的是找到只登录过一次的用户,并查明那是什么时候。

我使用

找到了只登录过一次的用户
SELECT 
    U.FirstName, U.LastName, COUNT(L.UserID) AS Visits
FROM 
    LoginSession L
JOIN 
    Users U ON U.UserID = L.UserID
GROUP BY 
    U.FirstName, U.LastName
HAVING 
    COUNT(L.UserID) = 1

但我也想拉过那些用户的L.StartDate。如果我将它添加到 select 查询中,我会得到一个错误,因为它不包含在聚合函数或 GROUP BY 子句中。如果我将它添加到 GROUP BY 行(以避免该错误),我会轻松地将每次登录标记为 1 次访问!

我也试过使用子查询,但我得到了一个错误,因为它返回了不止一个结果。

我真的被难住了!

您可以通过聚合来做到这一点:

select UserId, min(StartDate) as StartDate
from LoginSession ls
group by UserId
having count(*) = 1;

min() returns 你想要的值,因为匹配的只有一行。您可以使用加法 join 来获取有关用户的其他信息。

select u.*, lsu.StartDate
from Users u join
     (select UserId, min(StartDate) as StartDate
      from LoginSession ls
      group by UserId
      having count(*) = 1
     ) lsu
     on lsu.UserId = u.UserId;

您可以使用 COUNT 的窗口版本:

SELECT FirstName, LastName, StartDate
FROM (
  SELECT U.FirstName, U.LastName, L.StartDate,
         COUNT(*) OVER (PARTITION BY U.UserID) AS cnt
  FROM LoginSession L
  JOIN Users U ON U.UserID = L.UserID ) AS t
WHERE t.cnt = 1

COUNTOVER 子句将 return 每个 U.UserID 的记录数。使用外部查询,您可以准确获取这些记录。

Demo here