没有运气在子选择中获得最近的条目:ORA-00904:无效的标识符和ORA-06553:调用中的参数的数量或类型错误

时间:2014-07-25 14:11:19

标签: sql oracle subquery

我看过很多关于这个主题的帖子,但没有一个解决方案解决了我的问题。

简而言之,我有一个users表和一个user_history表。每个用户可以有0个或更多user_history条目。 user_history表具有状态列。我想要做的就是获取用户列表以及最新user_history条目的状态列的值。我无法让它发挥作用。我试过了:

select u.id, u.name, 
(select status from (select status, rownum as rn from user_history uh where uh.user_id = u.id    
order by created_date desc) where rn = 1) status
from users u;

这给了我一个“ORA-00904:无效的标识符,u.id”错误。根据我的阅读,Oracle不允许您从子子选择(具有rownum的子选择)中访问外部选择'u.id'。从第一个子选择它工作正常,但正如我所说,我可以在user_history中有n个条目,我只需要最新的。

我也尝试过使用内连接:

select u.id, u.name, h.status
from users u
inner join (select user_id, status, rownum as rn from user_history where user_id = u.id order by created_date desc) h on u.id = h.user_id where h.rn = 1;

这给了我可怕的“ORA-06553:呼唤你的错误数量或类型的论点”......我试图通过使用不同但无效的方法进行修复。

我也尝试过使用row_number(),over和partition ...其他类型的内连接与select ...没有任何东西可以获取我需要的数据。

有人可以帮我解决这个(看似简单的)简单查询吗?

2 个答案:

答案 0 :(得分:1)

这样的事情会起作用吗?它还会消除查询中的标量并且更容易调试,因为您可以独立运行内部查询(uh)并评估其结果。

with uh as (
  select
    u.id, u.name, uh.status, uh.created_date,
    max (uh.created_date) over (partition by uh.user_id) as max_date
  from
    users u,
    user_history uh
  where
    u.id = uh.user_id
)
select
  id, name, status
from uh
where created_date = max_date

- 编辑 -

为了它的价值,我加载了一些样本数据:

用户

1   Bilbo
2   Fatty
3   Pippin
4   Balin

用户历史

1   one     1/1/2014
1   two     1/2/2014
1   three   1/3/2014
2   four    1/4/2014
2   five    1/5/2014
2   six     1/6/2014
3   seven   1/7/2014
3   eight   1/8/2014
3   nine    1/9/2014

这是输出:

1   Bilbo   three
2   Fatty   six
3   Pippin  nine

如果您有多个具有完全相同“日期”字段的历史记录,则以下是row_number备选方案。

with uh as (
  select
    u.id, u.name, uh.status,
    row_number() over 
       (partition by u.id order by uh.created_date desc) as rn
  from
    users u,
    user_history uh
  where
    u.id = uh.user_id
)
select
  id, name, status
from uh
where rn = 1

答案 1 :(得分:1)

过去,查询看起来像这样

select 
    u.id, 
    u.name, 
    uh.status
from 
    users u 
        inner join
    (select 
         user_id, 
         status 
     from 
         user_history h 
     where 
         created_date = (select 
                             max(created_date) 
                         from 
                             user_history d 
                         where 
                             h.user_id = d.user_id)
     ) uh
         on u.id = uh.user_id;

这里有一个相关的子查询,可以为您提供最新的历史记录。它将为每一行执行,因此执行速度有点慢。并且您将其与用户表一起加入以获取您的状态。 我没有测试过,但它看起来不错。