Oracle为表

时间:2017-06-21 14:50:51

标签: sql oracle

我遇到了SQL问题。

基本上,我有一个存储在名为ACTIONS的表中的操作列表。这些可能发生在具有唯一ID的对象上。每个对象可以有多个动作
我需要做的是选择最近操作的列状态为2的所有对象。

数据看起来像这样:

OBJECT DATE                STATUS
------ ------------------- ------
OBJ1   13/11/2017 16:45:55      1
OBJ1   12/11/2017 15:45:55      2
OBJ2   13/11/2017 06:42:55      2
OBJ2   12/11/2017 16:45:55      1

输出将是: OBJ2

查询看起来像这样:

SELECT ID_OBJECT 
FROM ACTIONS
WHERE LASTACTIONSTATUS = 2

我最初尝试选择上一个操作的状态的子查询,但我的问题是我无法将我的Object的值传递给子查询。

尝试使用group by和order by,但由于表中有多个对象,我无法获得所需的所有对象

有没有人知道如何做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:4)

这是一个基本的聚合查询。您按OBJ分组。您在组级别具有条件,这意味着它应该在HAVING子句中。对于最近的STATUS,条件为DATE的值;这是通过FIRST/LAST函数完成的(由于某种原因,许多开发人员似乎都不熟悉它,包括许多经验丰富的开发人员)。 https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions065.htm#SQLRF00641

with
     test_data ( obj, dt, status ) as (
       select 'OBJ1', to_date('13/11/2017 16:45:55', 'dd/mm/yyyy hh24:mi:ss'), 1 from dual union all
       select 'OBJ1', to_date('12/11/2017 15:45:55', 'dd/mm/yyyy hh24:mi:ss'), 2 from dual union all
       select 'OBJ2', to_date('13/11/2017 06:42:55', 'dd/mm/yyyy hh24:mi:ss'), 2 from dual union all
       select 'OBJ2', to_date('12/11/2017 16:45:55', 'dd/mm/yyyy hh24:mi:ss'), 1 from dual
     )
-- End of test data (not part of the solution!) SQL query begins BELOW THIS LINE.
select   obj
from     test_data
group by obj
having   min(status) keep (dense_rank last order by dt) = 2
;

OBJ
----
OBJ2

答案 1 :(得分:0)

  

选择最近操作具有列状态的所有对象   在2

SELECT ID_OBJECT 
FROM
 (
    SELECT ID_OBJECT, 
       CASE
         WHEN ROW_NUMBER()        -- most recent row
              OVER (PARTITION BY ID_OBJECT
                    ORDER BY any_column_to_determine_most_recent DESC) = 1
          AND LASTACTIONSTATUS = 2 -- matches status 2
         THEN 1
         ELSE 0
       END AS flag
    FROM ACTIONS
 ) dt
WHERE flag = 1 -- only return matching rows

答案 2 :(得分:0)

您可以尝试以下操作(我没有测试它;可能有一些错误):

SELECT *
FROM
(
  SELECT act1.*
  FROM   actions act1
  WHERE  NOT EXISTS (SELECT act2.*
                     FROM   actions act2
                     WHERE  act2.id_object = act1.id_object
                       AND  act2.action_date > act1.action_date)
) recent
WHERE recent.lastactionstatus = 2;