SQL 选择最近的日期(W/三个 Table 加入)

SQL Selecting Most Recent Date (W/ Three Table Join)

使用下面的 SQL 查询我试图从 Interactive_Sessions.Sessiondate 检索最近的会话日期,同时还显示来自其他两个 table 的信息(Interactive.Users & Patroninfo) 通过使用 join

想要这样的东西

JDOE     Jane     DOE    1234     janedoe@jane.com     10/27/14 10:24
JDOA     Jane     DOA    1345     Janedoe@jana.com     11/13/17 12:34

以下是我目前正在处理的内容,我确保如何解决我在尝试执行时遇到的错误。这些是我在 MAX 中缺少的东西吗?

Select 
        INTERACTIVE_USERS.USERID, PATRONINFO.FIRSTNAME, PATRONINFO.LASTNAME, 
        PATRONINFO.PATRONID, INTERACTIVE_USERS.EMAIL, 
        MAX(INTERACTIVE_SESSIONS.SESSIONDATE)
FROM 
        INTERACTIVE_SESSIONS
JOIN 
        INTERACTIVE_USERS
ON 
        INTERACTIVE_SESSIONS.USERID = INTERACTIVE_USERS.USERID
JOIN 
        PATRONINFO
ON 
        INTERACTIVE_USERS.PID = PATRONINFO.PATRONID
GROUP 
        BY INTERACTIVE_USERS.USERID, PATRONINFO.FIRSTNAME, PATRONINFO.LASTNAME, PATRONINFO.PATRONID, INTERACTIVE_USERS.EMAIL
ORDER BY 
        MAX(INTERACTIVE_SESSIONS.SESSIONDATE)

我的问题是,当我按照语句离开组时,收到 ORA-00904 错误标识符无效,但我已验证 table 名称完全匹配。

当我删除 Group by 语句时,我得到的 ORA-00937 不是单组函数,我通常会用 Group BY

有没有人经历过类似的事情?有没有什么技巧可以解决这种错误,还是我太笨了,错过了一些明显的东西?

或者我已经尝试过这个但是它只出现了最近的 Interactive_Sessions.Sessiondate 对于任何 Interactive_Users.Userid 而不是每个 Interactive_Users.Userid

Select 
     INTERACTIVE_USERS.USERID, PATRONINFO.FIRSTNAME, PATRONINFO.LASTNAME, 
     PATRONINFO.PATRONID, INTERACTIVE_USERS.EMAIL, 
     INTERACTIVE_SESSIONS.SESSIONDATE
FROM 
     INTERACTIVE_SESSIONS
JOIN 
     INTERACTIVE_USERS
ON
     INTERACTIVE_SESSIONS.USERID = INTERACTIVE_USERS.USERID
JOIN 
     PATRONINFO
ON
     INTERACTIVE_USERS.PID = PATRONINFO.PATRONID
WHERE 
    interactive_sessions.sessiondate=(Select 
    MAX(Interactive_sessions.sessiondate) from Interactive_sessions)

我建议将会话 table 减少到每个用户 ID 仅一行,并在该过程中导出所需的日期。这意味着引入一个子查询,您当前有一个简单的连接。下面有一个选项使用 ROW_NUMBER() 将值 1 提供给 "latest" 日期(按降序排列)。

SELECT
      INTERACTIVE_USERS.USERID
    , PATRONINFO.FIRSTNAME
    , PATRONINFO.LASTNAME
    , PATRONINFO.PATRONID
    , INTERACTIVE_USERS.EMAIL
    , IESSIONS.SESSIONDATE
FROM INTERACTIVE_USERS
JOIN PATRONINFO ON INTERACTIVE_USERS.PID = PATRONINFO.PATRONID
JOIN (
      SELECT USERID, SESSIONDATE
            , row_number() over(partition by USERID, order by SESSIONDATE DESC) rn
      FROM INTERACTIVE_SESSIONS
      ) ISESSIONS ON INTERACTIVE_USERS.USERID = ISESSIONS.USERID
                 AND ISESSIONS.RN = 1
ORDER BY IESSIONS.SESSIONDATE
;

或者,在子查询中使用 GROUP BY(这是一种更传统的方法):

SELECT
      INTERACTIVE_USERS.USERID
    , PATRONINFO.FIRSTNAME
    , PATRONINFO.LASTNAME
    , PATRONINFO.PATRONID
    , INTERACTIVE_USERS.EMAIL
    , IESSIONS.SESSIONDATE
FROM INTERACTIVE_USERS
JOIN PATRONINFO ON INTERACTIVE_USERS.PID = PATRONINFO.PATRONID
JOIN (
      SELECT USERID, MAX(SESSIONDATE) SESSIONDATE
      FROM INTERACTIVE_SESSIONS
      GROUP BY USERID
      ) ISESSIONS ON INTERACTIVE_USERS.USERID = ISESSIONS.USERID
ORDER BY IESSIONS.SESSIONDATE
;

第二种方法足以满足您当前的查询,但了解这两种方法会很有用。使用 GROUP BY 方法(例如),您还可以使用 COUNT(*) 获取会话数,这在 row_number() 方法中是做不到的。但是,如果您需要与 "latest date" 位于同一行的会话 table 中的更多列,则 row_number() 方法可以实现这一点。

关于ORA-00904相关查询。如果您使用这样的列别名 MAX(INTERACTIVE_SESSIONS.SESSIONDATE) AS MAX_SESS_DT 那么您可以在 order 子句中使用该列别名:ORDER BY MAX_SESS_DT