The SurrealDB documentation states that the concept of JOINs is replaced through the use of Record links. But is it still possible to JOIN tables based on arbitrary columns?
Consider the following tables:
CREATE user:1 SET
name = 'User1',
favouriteDay = 'Monday'
;
CREATE user:2 SET
name = 'User2',
favouriteDay = 'Tuesday'
;
CREATE motto:1 SET
day = 'Monday',
motto = 'Best day of the week'
;
CREATE motto:2 SET
day = 'Tuesday',
motto = 'Second best day of the week'
;
Is it possible to write a query to get the following result (without changing the underlying data model)?
"result": [
{
"favouriteDay": "Monday",
"id": "user:1",
"name": "User1",
"motto": "Best day of the week"
},
{
"favouriteDay": "Tuesday",
"id": "user:2",
"name": "User2",
"motto": "Second best day of the week"
}
]
There is indeed a way to JOIN data in SurrealDB using SPLIT
.
A query joining the two tables user
and motto
would look like this:
SurrealDB
SELECT id, name, favouriteDay, motto.motto as motto
FROM (
SELECT *, (SELECT * FROM motto) as motto
FROM user
SPLIT motto
)
WHERE favouriteDay = motto.day;
SQL-equivalent
SELECT id, name, favouriteDay, motto
FROM user JOIN motto ON user.favouriteDay = motto.day
Explanation:
We first query all the users and add every motto to each user.
SELECT *, (SELECT * FROM motto) as motto FROM user
We can then use SPLIT
to unwind every element in the motto
array of each user
to a separate row.
SELECT *, (SELECT * FROM motto) as motto FROM user SPLIT motto
Lastly, we take the result of this query and filter all the rows where favouriteDay
and motto.motto
match. We also pull out the motto
string from the motto
object to format the output to the the desired result.
SELECT id, name, favouriteDay, motto.motto as motto FROM (
SELECT *, (SELECT * FROM motto) as motto FROM user SPLIT motto
)
WHERE favouriteDay = motto.day;
[
{
"favouriteDay":"Monday",
"id":"user:1",
"motto":"Best day of the week",
"name":"User1"
},
{
"favouriteDay":"Tuesday",
"id":"user:2",
"motto":"Second best day of the week",
"name":"User2"
}
]