我遇到了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,但由于表中有多个对象,我无法获得所需的所有对象
有没有人知道如何做到这一点?
谢谢!
答案 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;