The tag operation has a variety of applications such as generating surrogate keys and finding the nth smallest or largest item.
Tag
The tag operator takes a relational expression, an ordered set of attributes and a tag attribute name.
Each attribute name in the ordered set can be prefixed with - to use a descending order, otherwise an ascending order is used.
An integer attribute is added to each tuple in the relational expression, incrementing within the common values of the ordered set.
Again, given the example SP relvar:
SP
| SNO | PNO | QTY |
|---|---|---|
| S1 | P1 | 300 |
| S1 | P2 | 200 |
| S1 | P3 | 400 |
| S1 | P4 | 200 |
| S1 | P5 | 100 |
| S1 | P6 | 100 |
| S2 | P1 | 300 |
| S2 | P2 | 400 |
| S3 | P2 | 200 |
| S4 | P2 | 200 |
| S4 | P4 | 300 |
| S4 | P5 | 400 |
We can issue tags within the SNO (ascending) using the tag operator.
For example:
tag(SP, {SNO}, p_serial)
| SNO | PNO | QTY | p_serial |
|---|---|---|---|
| S1 | P1 | 300 | 0 |
| S1 | P2 | 200 | 1 |
| S1 | P3 | 400 | 2 |
| S1 | P4 | 200 | 3 |
| S1 | P5 | 100 | 4 |
| S1 | P6 | 100 | 5 |
| S2 | P1 | 300 | 0 |
| S2 | P2 | 400 | 1 |
| S3 | P2 | 200 | 0 |
| S4 | P2 | 200 | 0 |
| S4 | P4 | 300 | 1 |
| S4 | P5 | 400 | 2 |
Nth smallest
We can tag the results of a quota operation and then filter it to find the nth smallest item. For example, the part(s) with the 2nd smallest weight:
tag(quota(P{WEIGHT}, {WEIGHT}, 2), {-WEIGHT}, t)[t=0] & P
| WEIGHT | t | PNO | PNAME | COLOR | CITY |
|---|---|---|---|---|---|
| 14 | 0 | P4 | Screw | Red | London |
Nth largest
We can tag the results of a quota operation and then filter it to find the nth largest item. For example, the part(s) with the 2nd largest weight:
tag(quota(P{WEIGHT}, {-WEIGHT}, 2), {WEIGHT}, t)[t=0] & P
| WEIGHT | t | PNO | PNAME | COLOR | CITY |
|---|---|---|---|---|---|
| 17 | 0 | P2 | Bolt | Green | Paris |
| 17 | 0 | P3 | Screw | Blue | Rome |
These could be made into relational operators - see the Relation operators section for details.