Reputation: 25
Got 3 tables, said
{
id: number,
content: string
}
player
{
id: number,
name: string
}
is_mail_read
{
mail_id: number,
player_id: number
}
What I want to achieve:
Given a player_id, return the mails with a column is_read
which is true (or 1) if there is a record in is_mail_read
, false if there isn't.
For example:
[
{
id: 2,
content: "I am a mail",
is_read: true
},
{
id: 3,
content: "I am a mail too",
is_read: false
},...
]
I have tried left join but got no idea what to do next. The database is MariaDB.
Upvotes: 0
Views: 41
Reputation: 1269953
I would use exists
:
select m.*,
(exists (select 1
from is_mail_read imr
where imr.mail_id = m.id and
imr.player_id = ? -- your desired player id
)
) as read_flag
from mail m;
Upvotes: 1
Reputation: 51888
You're on the right track with using LEFT JOIN. Now you simply check, if for the record in the mail
table there is a record in the player
table by checking if the joined record is NULL or not.
I'm assuming that you want to display all mails and return the info if a mail is read for a specific player. Then you have to filter for the player in the JOIN
clause, not the WHERE
clause. If you do it in the WHERE
clause, you implicitly turn the LEFT JOIN
into an INNER JOIN
. Except when you write the WHERE
clause like
WHERE p.name = "John" OR p.name IS NULL
So your query should look like this:
SELECT
m.id,
m.content,
IF(p.id IS NULL, false, true) AS is_read
FROM
mail m
LEFT JOIN is_mail_read imr ON m.id = imr.mail_id
LEFT JOIN player p ON imr.player_id = p.id AND p.name = "John"
Upvotes: 1