2016-10-20 96 views
0

的功能,我尝试创建一个视图,或只是一个选择的时刻,在此基础上功能:SQL选择1行3 MAX/MIN领域

SELECT 
    FLAG 
FROM 
(
    SELECT 
    TE.FLAG 
    FROM 
    EVT E 
    INNER JOIN EVT_TYP TE ON TE.ID = E.FK_TYPE_EVT 
    WHERE 
    E.FK_OBJECT = NUMOBJECT 
    order by 
    trunc(E.EVT_DATE) desc, 
    e.evt_number desc, 
    e.id desc 
) 
where 
    rownum = 1; 

NUMOBJECT是函数的参数。函数为该NUMOBJECT返回一个FLAG。 我想为每个E.FK_OBJECT IN EVT表选择一个标志。

问题是我可以在同一天的一个E.FK_OBJECT EVT表中有几行,并且我没有时间部分日期,大部分时间。 E.evt_number可以是int或NULL。 E.id与E.EVT_DATE的顺序并不相同。

我不知道如何才能成功,你能帮我吗?我尝试与imbricates选择,但看起来像它是不可能的,因为NULL e.evt_number。

我使用Oracle DB。

编辑: 样本数据: Heberger image http://img15.hostingpics.net/thumbs/mini_229922Sanstitre.png

我尝试这样做:

SELECT E.Fk_Object 
    ,TE.FLAG 
FROM (
    SELECT 
     E.Fk_Object 
     ,E.EVT_DATE 
     ,E.evt_number 
     ,MAX(E.id) id 
    FROM (
     SELECT 
      E.Fk_Object 
      ,E.EVT_DATE 
      ,MAX(NVL(e.evt_number, - 1)) evt_number 
     FROM (
      SELECT 
       E.Fk_Object 
       ,MAX(E.EVT_DATE) EVT_DATE 
      FROM EVT E 
      GROUP BY E.Fk_Object 
      ) E_MAX 
     INNER JOIN EVT E ON E.Fk_Object = E_MAX.Fk_Object 
      AND E.EVT_DATE = E_MAX.EVT_DATE 
     WHERE e.flg_suppression = 0 
      AND e.evt_date IS NOT NULL 
     GROUP BY E.Fk_Object 
      ,E.EVT_DATE 
     ) E_MAX_2 
    INNER JOIN EVT E ON E.Fk_Object = E_MAX_2.Fk_Object 
     AND E.EVT_DATE = E_MAX_2.EVT_DATE 
     AND NVL(e.evt_number, - 1) = NVL(E_MAX_2.evt_number, - 1) 
    GROUP BY E.Fk_Object 
     ,E.EVT_DATE 
     ,E.evt_number 
    ) E_MAX_3 
left JOIN EVT E ON E.Fk_Object = E_MAX_3.Fk_Object 
    AND E.EVT_DATE = E_MAX_3.EVT_DATE 
    AND NVL(e.evt_number, - 1) = NVL(E_MAX_3.evt_number, - 1) 
    AND E.id = E_MAX_3.id 
INNER JOIN EVT_TYP TE ON TE.id = E.FK_EVT_TYP 
ORDER BY 2 
    ,3; 

但它不给我相同的结果,做功能

+0

向我们展示样本数据和预期的输出。为什么'NUMOBJECT'没有参数? –

+0

下面是一个示例:http://hpics.li/9bb51cf NUMOBJECT是参数的名称,它的值是一个数字,如150146,就像在屏幕上 –

+0

您的第一个查询(不是函数)会为给定的选择最近的记录对象并返回此记录的标志。这与你真正想要的有什么不同? –

回答

0

相反NVL(E_MAX_2.evt_number, - 1)的我必须使用NVL(E_MAX_2.evt_number,99),而不是忘记了TRUNC()用于E.EVT_DATE保持比同阶的功能,它是确定!因此,它在12秒内运行。这个功能以前是54。 我会测试创建一个视图,看看它是否更好。

0

如果我理解正确,那么您正在查找一个查询,它不仅为您提供最新的标志,而且还提供了多个对象。您可以通过选择所有这些对象的记录,然后按应用Oracle的KEEP FIRST/LAST的对象进行分组。

select 
    e.fk_object, 
    max(te.flag) keep (dense_rank first 
    order by trunc(e.evt_date) desc, e.evt_number desc, e.id desc) as current_flag 
from evt e 
join evt_typ et on et.id = e.fk_type_evt 
where fk_object in (numobject1, numobject2, numobject3) 
group by e.fk_object; 

同样可以用作子查询。比方说,你有一个表OBJECTS与一列STATUS,你想显示他们目前的标志每个状态的“新”的所有对象:

select o.*, flags.current_flag 
from objects o 
join 
(
    select 
    e.fk_object, 
    max(te.flag) keep (dense_rank first 
     order by trunc(e.evt_date) desc, e.evt_number desc, e.id desc) as current_flag 
    from evt e 
    join evt_typ et on et.id = e.fk_type_evt 
    group by e.fk_object 
) flags on flags.fk_object = o.id 
where o.status = 'new';