Возврат только самых последних значений запроса

Я работаю над получением состояний агентов из системы центра обработки вызовов и хотел бы знать, есть ли в Informix способ получить только самую последнюю запись значения из таблицы.

Таблица, над которой я работаю, регистрирует изменяющееся состояние для агентов, которое я хотел бы представить на веб-странице. Однако он регистрирует каждое изменение. Это запрос;

select a.eventdatetime
        ,b.resourcename
        ,b.extension
        ,a.eventtype 
    from agentstatedetail as a
        ,resource as b
        ,team as c 
where date(eventdatetime) = date(current) 
    and (a.agentid = b.resourceid) 
    and (b.assignedteamid = 10) 
    and (c.teamname like 'teamnamehere %') 
group by a.eventdatetime
    ,b.resourcename
    ,b.extension
    ,a.eventtype 
order by eventdatetime desc

Запрос работает нормально, но меня интересует только самая последняя запись resourcename, игнорируя все старые. Возможно ли это с Informix?


person Kimomaru    schedule 06.02.2014    source источник


Ответы (2)


Конечно. Вам просто нужен подзапрос для определения самой последней записи для каждого агента. Что-то вроде (непроверено):

select a.eventdatetime
        ,b.resourcename
        ,b.extension
        ,a.eventtype 
    from agentstatedetail as a
        ,resource as b
        ,team as c
        ,(SELECT agentid, MAX(eventdatetime) AS lastevent
           FROM agentstatedetail 
           WHERE DATE(eventdatetime) = TODAY
           GROUP BY agentid) AS d 
where (a.agentid = b.resourceid) 
    and (b.assignedteamid = 10) 
    and (c.teamname like 'teamnamehere %') 
    and (d.agentid = a.agentid and a.eventdatetime = d.lastevent)
group by a.eventdatetime
    ,b.resourcename
    ,b.extension
    ,a.eventtype 
order by eventdatetime desc

Возможно, вам придется взглянуть на индексацию agentstatedetail, чтобы добиться максимальной эффективности.

ИЗМЕНИТЬ

В соответствии с вашим комментарием об избежании вложенного запроса и обработке пропуска уже замеченных значений агентидов, это довольно тривиальное решение на стороне клиента. Я не знаю точно, как вы справляетесь с этим на стороне PHP, но в основном вы хотите сделать что-то вроде этого:

$data = $db->query("select a.eventdatetime, b.resourcename, b.extension, a.eventtype
                    from agentstatedetail as a, resource as b, team as c 
                    where date(eventdatetime) = date(current)
                    and (a.agentid = b.resourceid) and (b.assignedteamid = 10)
                    and (c.teamname like 'ITS Help Desk %')
                    group by a.eventdatetime, b.resourcename,
                             b.extension, a.eventtype
                    order by eventdatetime desc");

$agent = Array();

foreach($data as $row){
    if(!$agent[$row['RESOURCENAME']]++) {
        echo
        "<TR bgcolor='#D0D0D0'><TD class='body'>" . $row['RESOURCENAME'] . 
        "<TD class='body'>" . $row['EVENTTYPE'] . 
        "</TD>";
    }
}

Ассоциативный массив $agent отслеживает, сколько записей было просмотрено для конкретного агента. Когда он пуст, это первое появление. Точное ненулевое число на самом деле бесполезно, мы просто используем постинкремент для повышения эффективности, вместо того, чтобы явно указывать $agent[$row['RESOURCENAME']] в цикле.

person RET    schedule 06.02.2014
comment
Привет, Ret - этот подзапрос определенно помогает, но он не решает напрямую мою конкретную проблему (хотя я воздаю вам должное). Когда я запускаю ваш запрос, это занимает 4 минуты. Мой запрос занимает 15 секунд. Это связано с сервером, к которому я выполняю запрос - таблицы, перечисленные в этих запросах, на самом деле не должны запрашиваться. Итак, мне интересно, есть ли способ выполнить мой 15-секундный запрос, но использовать PHP, чтобы сохранить только самые последние записи? - person Kimomaru; 07.02.2014
comment
Как я предположил, вы, вероятно, захотите убедиться, что у вас есть индекс для agentid и eventdatetime, чтобы избежать сканирования предположительно довольно большой таблицы. Если вы хотите просто пропустить записи агента, которые вы видели раньше, это совершенно другое решение. См. Отредактированный ответ выше. - person RET; 08.02.2014
comment
@Kimomaru, я согласен с RET, индекс должен помочь в решении проблемы производительности, но я предлагаю перейти к подзапросу отношений с другими таблицами, используемыми для фильтрации, потому что это зависит от объема данных, которые у вас есть в agentstatedetail (я полагаю, это ваш самая большая таблица) вы избежите сканирования ненужных записей подробностей агента (не охваченных фильтром), тогда основной запрос будет использоваться только для получения описания данных (не применять фильтр к нему, только базовое отношение идентификатора с подзапросом ). - person ceinmart; 09.02.2014
comment
Увидев ваш другой вопрос с PHP-кодом в нем, я обновил свой псевдокод. - person RET; 09.02.2014
comment
Привет, ребята, я пробовал код, и он отлично работает. В последние пару дней, когда я думал об этом, мои мысли также были направлены на это - создать массив, добавить в него объекты на каждом проходе, затем проверить, существует ли объект в проходе, прежде чем повторять его. . Я просто хочу убедиться, что понимаю это правильно; строка! $ agent [$ row ['RESOURCENAME']] ++ она делает две вещи? Он добавляет объект в массив $ agent, а затем проверяет, установлен ли он перед запуском операции эха? - person Kimomaru; 09.02.2014
comment
Кроме того, еще одна вещь, если это имеет значение - я не могу вносить какие-либо изменения в саму базу данных Informix, как вы предложили (например, добавление индекса). Это заблокированное устройство, и я действительно должен выполнять запросы только из двух конкретных таблиц. Приведенный выше запрос извлекает информацию, которая мне действительно нужна, но выполняется очень медленно, поэтому мне нужно было бы согласиться на 15-секундный запрос и опубликовать его на PHP, чтобы получить нужный мне результат, к сожалению :( - person Kimomaru; 09.02.2014
comment
Отвечая на ваш второй последний вопрос, !$agent[$row['RESOURCENAME']]++ выполняет эти две вещи, но, что очень важно, наоборот. Отрицание в начале означает, что это возвращает истину, если ключ не существует в массиве, а постинкремент в конце добавляет к нему 1, что означает, что он будет существовать на любом последующем проходе. - person RET; 10.02.2014
comment
Спасибо, RET. Весьма признателен. - person Kimomaru; 10.02.2014

Если ваш запрос выполняется медленно, используйте объясните, чтобы увидеть причину, а также проанализировать использование индекса. это может быть:

дата (eventdatetime) = дата (текущая)

состояние. если у вас есть хороший индекс для eventdatetime (который равен datetime от года к секунде?), то, возможно, используйте его таким образом:

eventdatetime> = 'гггг-мм-дд 00:00:00' и eventdatetime ‹= 'гггг-мм-дд 23:59:59'

где гггг-мм-дд = сегодня

person Bartek    schedule 09.02.2014