简体   繁体   中英

Progress 4GL query

I have a table say 'Employee' with one single field say 'Name'. There are say 9 records in the table. I need to write a 'for each' query with the help of 'where' clause by which i will be able to view/display one selected name (say 'Sheldon' being the 6th record of the 9) at the very first and the rest 8 records(names) in alphabetical order. **Note: Only by constructing a query as such. No concept of temp-tables, buffers. nothing allowed within the 'for each' block other than 'display' statement.

I think that you are saying that you have an employee table with records like:

Dan
Gus
Mike
Paul
Rich
Sheldon
Shelley
William
Xavier

And you want the output to be:

Sheldon
Dan
Gus
Mike
Paul
Rich
Shelley
William
Xavier

You cannot do this in a single FOR EACH because you have two quite distinct queries. One to find the "sheldon" record (or records -- you didn't say if they are unique) and one to find all of the rest.

You could do it like so:

do with frame a.
  for each employee no-lock where name = "Sheldon":
    display name with frame a 10 down.
    down with frame a.
  end.
  for each employee where name <> "Sheldon" by name:
    display name with frame a.
    down with frame a.
  end.
end.

(The "do with frame a" and various other "frame a" bits are just to use a single frame. If you don't care about that you don't need those bits.)

If you are willing to expand your horizons a bit and stoop to using FIND you could do it like so:

find employee no-lock where name = "sheldon".

repeat:

  if not available employee then leave.

  display name with 10 down.

  if name = "sheldon" then
    find first employee no-lock where name <> "sheldon" no-error.
   else
    find next employee where name <> "sheldon" no-error.

end.

For obvious reasons I haven't spent much time testing this but the vile trickery appears to be:

for each employee where name = "sheldon" or name <> "sheldon":
  display name.
end.

As I said -- I'd use this as a disqualifying test. If you think like this then your code is more trouble than it is worth. IMHO.

Normally you'd use a FIND for this, but since you asked for a FOR EACH - here's one w/out the WHERE. You can easily add that to get any end result you want.

FOR EACH employee  
    NO-LOCK 
    BY Employee.name:

    DISPLAY employee.name WITH DOWN.

END.

Use two for eaches. first one returns from your selected name and larger alphabetical and the 2nd starts from beginning and breaks as soon as get to your selected name. This will display fields alphabetically starting at your selected name. This assume name is alphabetically sorted key field else can use other options to sort values.

Sorry did not test code, or worry about formatting. Also not sure by what you mean the rest must be alphabetically so here are two variations.

With using a temp table it would be even easier to do any 1 of these approaches.

Should be like this if you want to show sheldon and then alpha from sheldon onwards:

FOR EACH employee  where name >= "sheldon" NO-LOCK:
    DISPLAY employee.name.
END.

FOR EACH employee  NO-LOCK:
    if employee.name = "sheldon"
        break;
    DISPLAY employee.name.
END.

Should be like this if you want to show sheldon and then alpha from start, excluding sheldon:

FIND employee no-lock where name = "sheldon".
DISPLAY employee.name.

FOR EACH employee  NO-LOCK where name <> "sheldon":
    DISPLAY employee.name.
END.

A relatively non-evil way, for the record, which is safe against future releases of Openedge screwing with you:

for each employee 
    no-lock
    by (if employee.name = "sheldon" then 1 else 2)
    by employee.name
:
    display employee.
end.

...but the performance will be horrible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM