Using COALESCE and if in SPARQL for Nested If..Then..Else Statements

For example given the following (shamelessly borrowed) psuedocode:

If student’s grade is greater than or equal to 90 then

Display “A”

Else

If student’s grade is greater than or equal to 80 then

Display “B”

Else

If student’s grade is greater than or equal to 70 then

Display “C”

Else

If student’s grade is greater than or equal to 60 then

Display “D”

Else

Display “F”

Of course this can be implemented in SPARQL using nested IF statements:

BIND (
  IF(?grade >= 90, "A",
    IF(?grade >= 80, "B",
      IF(?grade >= 70, "C",
        IF(?grade >= 60, "D", "F")
      )
    )
  ) AS ?result
)

However, when the logic gets more complex, this can quickly become hard to read and debug.

So let’s look at COALESCE in more detail, the following taken from the SPARQL 1.1 Recommendation:

The COALESCE function form returns the RDF term value of the first expression that evaluates without error. In SPARQL, evaluating an unbound variable raises an error.

So for each conditional test, we just need to force our else to evaluate to an error when it does not match our test. This can be easily achieved using IF where we put our required output in the second argument and some expression that evaluates to an error as the third argument.

IF(?test, "Yay!", 1/0)

The “otherwise” case can be handled by adding a degenerative case that will always evaluate without error.

So the equivalent logic for our grades example can also be implemented in SPARQL using COALESCE:

BIND (
  COALESCE(
    IF(?grade >= 90, "A", 1/0),
    IF(?grade >= 80, "B", 1/0),
    IF(?grade >= 70, "C", 1/0),
    IF(?grade >= 60, "D", 1/0),
    "F"
  ) AS ?result
)

In the end it comes down to taste, but arguably the latter is a cleaner approach.