Let's say you've got an employee file, and an time worked file, such as you described. And you want to report what was the earliest time-in, and the latest time-out, for each employee on a given day.
So you might have a loop reading the employee file, and in that loop, you could chain out to the logical that @Martin described to get the last time-out, and another logical keyed with ascending time-in to get the least value there.
With SQL you could get the employee file information, as well as the earliest time-in and the latest time-out, all in a single read (fetch in SQL). It simplifies your code inside the loop quite a bit, doesn't it?
So here's the basic flow in pseudo-code:
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
Not too scary looking, is it? So let's see what the code might look like. Of course there is more than one way to do in SQL, but let's start simple with just an SQL Select statement. When you use RPG variables in SQL, you prefix them with a colon (':').
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;
Well, that's quite a SELECT statement, eh? A lot going on.
But it's organized into two parts. The first part is a table expression called h, where we get our times for each employee on that date. The second part lists all the result fields we want, which are taken from the table expression h and the employees file, wherever we can match the employee numbers in both files. The rows will be given to us sorted by last name, first name, and employee number.
So let's put this in 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;
Now you may at first hesitate at how much work is being done by the SELECT statement in the cursor. But by doing it all there you've simplified your I/O, and let the SQL optimizer work its magic to find the fastest way to get your data to you.