Как выбрать максимальное значение для поля с заданным условием?

Я делаю систему учета рабочего времени, где мой физический файл (PF) имеет следующие поля:

User ID(key field),Date,Time In,Time Out
......

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

как будет выглядеть источник RPGLE?

3 ответа

Решение

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

Допустим, у вас есть файл сотрудника и файл с отработанным временем, такой как вы описали. И вы хотите сообщить, какой был самый ранний и последний тайм-аут для каждого сотрудника в данный день.

Таким образом, у вас может быть цикл чтения файла сотрудника, и в этом цикле вы можете использовать логическую схему, описанную @Martin для получения последнего тайм-аута, и другой логический ключ с восходящим временем ожидания, чтобы получить наименьшее значение.,

С помощью SQL вы можете получить информацию о файле сотрудника, а также самый ранний и последний тайм-ауты за одно чтение (выборка в SQL). Это немного упрощает ваш код внутри цикла, не так ли?

Итак, вот основной поток в псевдокоде:

Declare a cursor with your SQL statement
Open the cursor
Fetch a row from the cursor
DoWhile status is ok
    Process your data
    Fetch the next record
EndDo
Close the cursor

Не слишком страшно, не правда ли? Итак, давайте посмотрим, как может выглядеть код. Конечно, есть несколько способов сделать это в SQL, но давайте начнем с простого оператора SQL Select. Когда вы используете переменные RPG в SQL, вы ставите их перед двоеточием (':').

    WITH h as
    ( SELECT empID, min(timein) as firstin, max(timeout) as lastout
        FROM workhours
        WHERE workdate = :myvariable
        GROUP BY empID
    )
    SELECT e.lastname, e.firstname, e.empnbr, h.firstin, h.lastout
      FROM h
      JOIN employees as e   on h.empID = e.empnbr
      ORDER BY e.lastname, e.firstname, e.empnbr;

Ну, это довольно утверждение SELECT, а? Многое происходит

Но это организовано на две части. Первая часть - это табличное выражение h, где мы получаем время для каждого сотрудника на эту дату. Во второй части перечислены все нужные нам поля результатов, которые взяты из табличного выражения h и файла сотрудников, где мы можем сопоставить номера сотрудников в обоих файлах. Строки будут переданы нам по фамилии, имени и номеру сотрудника.

Итак, давайте поместим это в RPG.

EXEC-SQL  DECLARE CURSOR C1 AS
              WITH h as
              ( SELECT empID, min(timein) as firstin, max(timeout) as lastout
                  FROM workhours
                  WHERE workdate = :myvariable
                  GROUP BY empID
              )
              SELECT e.lastname, e.firstname, e.empnbr, h.firstin, h.lastout
                FROM h
                JOIN employees as e   on h.empID = e.empnbr
                ORDER BY e.lastname, e.firstname, e.empnbr
                FOR READ ONLY;
EXEC-SQL  OPEN C1;
EXEC-SQL  FETCH FROM C1
            INTO :lname, :fname, :emp, :firsttime, :lasttime;
DoW &subst(SQLState,1,2) = '00';
    //
    // perform processing here
    //
    EXEC-SQL  FETCH FROM C1
                INTO :lname, :fname, :emp, :firsttime, :lasttime;
enddo;
EXEC-SQL  CLOSE C1;

Теперь вы можете сначала сомневаться, сколько работы выполняется оператором SELECT в курсоре. Но, сделав все это, вы упростили свой ввод-вывод и позволили оптимизатору SQL поработать над своей магией, чтобы найти самый быстрый способ получить ваши данные.

Встроенный SQL также будет работать:

SELECT MAX(timeout) 
INTO :outTime  
FROM PF 
WHERE userid = :selected_user_id
AND date = :selected_date`
Другие вопросы по тегам