Previous: Field Expressions, Up: Querying Recfiles


3.7 Sorted Output

This special field sets sorting criteria for the records contained in a record set. Its usage is:

     %sort: field1 field2 ...

Meaning that the desired order for the records will be determined by the contents of the fields named in the %sort value. The sorting is always done in ascending order, and there may be records that lack the involved fields, i.e. the sorting fields need not be mandatory.

It is an error to have more than one %sort field in the same record descriptor, as only one field list can be used as sorting criteria.

Consider for example that we want to keep the records in our inventory system ordered by entry date. We could achieve that by using the following record descriptor in the database:

     %rec: Item
     %type: Date date
     %sort: Date
     
     Id: 1
     Title: Staplers
     Date: 10 February 2011
     
     Id: 2
     Title: Ruler Pack 20
     Date: 2 March 2009
     
     ...

As you can see in the example above, the fact we use %sort in a database does not mean that the database will be always physically ordered. Unsorted record sets are not a data integrity problem, and thus the diagnosis tools must not declare a recfile as +invalid because of this. The utility recfix provides a way +to physically order the fields in the file (see Invoking recfix).

On the other hand any program listing, presenting or processing data extracted from the recfile must honor the %sort entry. For example, when using the following recsel program in the database above we would get the output sorted by date:

     $ recsel inventory.rec
     Id: 2
     Title: Ruler Pack 20
     Date: 2 March 2009
     
     Id: 1
     Title: Staplers
     Date: 10 February 2011

The sorting of the selected field depends on its type:

It is possible to specify several fields as the sorting criteria. In that case the records are sorted using a lexicographic order. Consider for example the following unsorted database containing marks for several students:

     %rec: Marks
     %type: Class enum A B C
     %type: Score real
     
     Name: Mr. One
     Class: C
     Score: 6.8
     
     Name: Mr. Two
     Class: A
     Score: 6.8
     
     Name: Mr. Three
     Class: B
     Score: 9.2
     
     Name: Mr. Four
     Class: A
     Score: 2.1
     
     Name: Mr. Five
     Class: C
     Score: 4

If we wanted to sort it by Class and by Score we would insert a %sort special field in the descriptor, having:

     %rec: Marks
     %type: Class enum A B C
     %type: Score real
     %sort: Class Score
     
     Name: Mr. Four
     Class: A
     Score: 2.1
     
     Name: Mr. Two
     Class: A
     Score: 6.8
     
     Name: Mr. Three
     Class: B
     Score: 9.2
     
     Name: Mr. Five
     Class: C
     Score: 4
     
     Name: Mr. One
     Class: C
     Score: 6.8

The order of the fields in the %sort field is significant. If we reverse the order in the example above then we get a different sorted set:

     %rec: Marks
     %type: Class enum A B C
     %type: Score real
     %sort: Score Class
     
     Name: Mr. Four
     Class: A
     Score: 2.1
     
     Name: Mr. Five
     Class: C
     Score: 4
     
     Name: Mr. Two
     Class: A
     Score: 6.8
     
     Name: Mr. One
     Class: C
     Score: 6.8
     
     Name: Mr. Three
     Class: B
     Score: 9.2

In this last case, Mr. One comes after Mr. Two because the class A comes before the class B even though the score is the same (6.8).