【问题标题】:oracle query is not workingoracle 查询不工作
【发布时间】:2014-07-08 15:55:12
【问题描述】:

我有两个名为 LOGIN 和 LOGIN_LOG 的表。在 LOGIN_LOG 表中,保存了每个用户每次登录的日期时间。在这两个表中 EMP_CODE 是公共列。我必须从登录表中选择所有用户名、位置以及从 LOGIN_LOG 表中的“上次登录时间”。我已经尝试过这样的事情,但没有工作。请帮忙。

SELECT 
LOGIN."NAME",
LOGIN.LOCATION,
LOGIN.WORKING_STATUS,
LV.LOGINDATETIME
FROM 
LOGIN 
LEFT OUTER JOIN 
(SELECT 
 LOGIN_LOG.EMP_CODE, 
 LOGIN_LOG.LOGINDATETIME 
 FROM LOGIN_LOG 
 ORDER BY LOGIN_LOG.LOGINDATETIME DESC
) AS LV
ON LOGIN.EMP_CODE=LV.EMP_CODE 
WHERE LOGIN.USER_TYPE='NSA';

【问题讨论】:

  • 它给出了错误 - ORA-00905: missing keyword
  • @mareckmareck:绝对不是。列(标识符)使用双引号引起来。单引号用于字符文字。
  • 这不是单引号,而是后引号。但实际上你是对的,在 Oracle 中你使用双引号。
  • @mareckmareck:反引号和单引号一样错误。标准 SQL(和 Oracle)使用双引号作为标识符。

标签: sql oracle join


【解决方案1】:

Oracle 不支持使用AS 作为表别名。

另外,您的查询没有意义。外部不需要派生表,派生表或子查询中的order by 根本没有任何意义。

所以应该是这样的:

SELECT login.name,
       login.location,
       login.working_status,
       lv.logindatetime
FROM login
  LEFT OUTER JOIN login_log lv ON login.emp_code = lv.emp_code
WHERE login.user_type = 'NSA'

编辑:我忽略了您获取最后一次登录的要求:

SELECT login.name,
       login.location,
       login.working_status,
       lv.logindatetime
FROM login
  LEFT JOIN (
     select emp_code, max(logindatetime) as logindatetime
     from login_log
     group by emp_code
 )  lv ON login.emp_code = lv.emp_code
WHERE login.user_type = 'NSA'

【讨论】:

  • 不工作。如果 login_log.logindatetime 是 lv,那么这个列如何可能是 lv.emp_code。错误是 ORA-00942:表或视图不存在
  • @user3807573:抱歉,我刚刚复制了您的代码。忽略了你犯的错误。现已更正
  • 我已经这样做了,但它给出了所有 logindateTime 但我必须按照我的问题中的描述只选择每个用户的最后登录日期时间。
  • @user3807573:查看我的编辑。我忽略了您获取最新登录信息的要求
【解决方案2】:

上面的查询有点混乱。在我看来,子查询是错误的。您不能依赖连接后结果的任何顺序。换句话说,如果您有一个表 A 和一个表 B,都已排序并且您进行了联接,则无法确定联接的结果也已排序。

我建议(不知道在您的情况下“不起作用”是什么意思):

SELECT L."NAME", L.LOCATION, L. WORKING_STATUS, LG.LOGINDATETIME
FROM LOGIN L
JOIN LOGIN_LOG LG on L.EMP_CODE=LG.EMP_CODE
WHERE L.USER_TYPE='NSA'
ORDER BY LG.LOGINDATETIME DESC

如果可能,总是更喜欢连接而不是子查询,因为 dbms 可以更好地处理它们(通过优化、索引等)

编辑:

当然,这里不需要LEFT OUTER JOIN,它可能会在查询执行器中产生开销,因此最好改用JOIN

EDIT2:

我想现在我遇到了问题。您需要使用GROUP BY 而不是ORDER BY

SELECT L."NAME", L.LOCATION, L. WORKING_STATUS, MAX(LG.LOGINDATETIME) AS LOGINDATETIME
FROM LOGIN L
JOIN LOGIN_LOG LG on L.EMP_CODE=LG.EMP_CODE
WHERE L.USER_TYPE='NSA'
GROUP BY L."NAME", L.LOCATION, L.WORKING_STATUS

【讨论】:

  • 我已经做到了,但它提供了所有 logindateTime 但我必须按照我的问题中所述只选择每个用户的最后登录日期时间
  • 所以你需要每个用户上次登录的日期时间吗?
  • 是的。实际上在 LOGIN_LOG 表中记录了每个用户每次登录的日期时间。我必须选择最后一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
相关资源
最近更新 更多