SQL Select 1 line in function of 3 MAX/MIN fields

时间:2016-10-20 13:12:57

标签: sql oracle

I try to create a view, or just a select for the moment, based on this function :

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 is the function parameter. Function returns one FLAG for that NUMOBJECT. I want to select one flag for each E.FK_OBJECT IN EVT table.

Problems are I can have several lines in EVT table for one E.FK_OBJECT the same day, and I don't have time part of the date, most of the time. E.evt_number can be int or NULL. And E.id haven't the same order that E.EVT_DATE.

I don't know how I can succeed it, can you help me please? I try with imbricates select but looks likes it's not possible beacause of NULL e.evt_number.

I work on Oracle DB.

edit : Sample of data : Heberger image http://img15.hostingpics.net/thumbs/mini_229922Sanstitre.png

I tried this :

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;

But it doesn't give me same results than function

2 个答案:

答案 0 :(得分:0)

完成!

而不是NVL(E_MAX_2.evt_number, - 1)我必须使用NVL(E_MAX_2.evt_number,99)并且不要忘记E.EVT_DATE的trunc()以保持与函数相同的顺序,并且没关系! ! 有了它,它在12秒内运行。这个功能之前是54。 我将测试创建一个视图,看看它是否更好。

答案 1 :(得分: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列,并且您希望显示所有状态对象' new'每个当前的旗帜:

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';