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

时间:2017-10-20 15:33:14

标签: sql max multiple-columns multiple-tables

使用下面的SQL查询我试图从Interactive_Sessions.Sessiondate检索最近的会话日期,同时还使用join

显示来自其他两个表(Interactive.Users& Patroninfo)的信息

想要这个的东西

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)

我的问题是当我离开group by语句时,我收到无效标识符的ORA-00904错误,但我已经验证了表名完全匹配。

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

有没有人经历过类似的事情?是否有任何技巧可以解决这种错误,或者我是否密集而错过了一些明显的错误?

或者我已经尝试了这个但是它只出现在最新的Interactive_Sessions.Sessiondate中,用于ANY 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)

1 个答案:

答案 0 :(得分:0)

我建议将每个用户ID的会话表减少到一行,并在该过程中派生所需的日期。这意味着引入一个子查询,您可以在其中进行简单的连接。下面有一个选项,使用ROW_NUMBER()为"最新"提供值1。日期(按降序排序)。

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()方法中是无法做到的。但是,如果您需要来自会话表的更多列,这些列与"最新日期"然后row_number()方法启用它。

关于ORA-00904相关查询。如果您使用此MAX(INTERACTIVE_SESSIONS.SESSIONDATE) AS MAX_SESS_DT之类的列别名,则可以在订单子句中使用该列别名:ORDER BY MAX_SESS_DT