2016-10-20 1 views
0

Я пытаюсь создать представление, или просто выбрать на данный момент, на основе этой функции:SQL Select 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 является параметром функции. Функция возвращает один FLAG для этого NUMOBJECT. Я хочу выбрать один флаг для каждой таблицы E.FK_OBJECT IN EVT.

Проблемы: я могу иметь несколько строк в таблице EVT для одного E.FK_OBJECT в тот же день, и большую часть времени у меня нет частичной даты. 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

Done!

Вместо 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'; 
Смежные вопросы