We can compare relations. Since the restrict operation returns a relation, we can compare two filtered results.
S[STATUS=20]
SNO | SNAME | STATUS | CITY |
---|---|---|---|
S1 | Smith | 20 | London |
S4 | Clark | 20 | London |
S[CITY="London"]
SNO | SNAME | STATUS | CITY |
---|---|---|---|
S1 | Smith | 20 | London |
S4 | Clark | 20 | London |
The equality comparison, using =
will return true
for this case.
S[STATUS=20] = S[CITY="London"]
true
We can also test whether one relation is a subset of another, using <=
.
This symbol is meant to resemble the subset symbol, ⊆
(which you can use instead, if your keyboard can create it).
S[STATUS=20] <= S[CITY="London"]
true
S[STATUS=20] <= S
true
S[STATUS=20] <= S[STATUS=30]
false
There is also a superset operator: >=
(or ⊇
).
And there are pure subset and pure superset operators (i.e. excluding the cases when both are equal): <
and >
(or ⊂
and ⊃
)
Heading
We can use the heading
function to get the set of attributes for a relation.
heading(S)
attr | type |
---|---|
CITY | str |
SNAME | str |
SNO | str |
STATUS | int |
And because this returns a relation we can do further operations on it. For example, to find the common attributes in S and SP:
heading(S) & heading(SP)
attr | type |
---|---|
SNO | str |
heading
with no parameter will return the heading for the current scope, i.e. each local variable plus globals (which includes persisted relvars for the current schema).
heading()
attr | type |
---|---|
Constraint | {name:str,rule:str} |
P | {PNO:str,PNAME:str,COLOR:str,WEIGHT:int,CITY:str} |
S | {SNO:str,SNAME:str,STATUS:int,CITY:str} |
SP | {SNO:str,PNO:str,QTY:int} |
error | {message:str} |
Cardinality
We can count how many tuples are in a relation using count()
.
count(S[STATUS=20])
2
We can check if a relation has no tuples using empty()
.
empty(dee)
false
empty(dum)
true
Degree
We can count how many attributes are in a relation using count
and heading
.
count(heading(S))
4
Quantification
We can add a boolean attribute to a relation (or use an existing one).
Then we can use the all
or exists
(or ∀
or ∃
if your keyboard can create them) operators to check if all or any tuples have the attribute set true.
exists(S{*, test:=(STATUS=20)}, test)
true
all(S{test:=(STATUS=20)})
false
all(S{test:=(STATUS<100)})
true
exists
and all
should be more efficient than counting filtered matches since they can short-circuit and finish early without necessarily checking all the tuples.