I am trying to retrieve a few things from the database with just one single query:
– the number of friend requests
– the number of new private messages
– the number of notifications
– and username of the user who eg. sent the PM to you or invited you to friends.
The user id specified below in the query is the user who is checking to see if there are any notifications for this user.
The problem is: if there are no notifications it will not return the number of friend requests or private messages as well.
This is the query I have build, and it works apart from the problem above:
SELECT
n.id,
n.type,
u.username,
COUNT(fr.friend_id) as frc,
COUNT(pm.pm_id) as pmc
FROM
notifications as n,
users as u
LEFT JOIN
private_messages as pm
ON
pm.to_user = '1'
AND
pm.status = 'unread'
LEFT JOIN
friends as fr
ON
fr.friend_id = '1'
AND
fr.status = 'pending'
WHERE
n.user_id='1'
AND
u.id = n.from_id
ORDER BY
n.id ASC
I am not sure what I am missing, so if anyone can share their sql knowledge and help me out I would deeply appreciate it.
Thanks!
Ps. I am still very new to more complex queries, so if I am completely off track with my above query, please do let me know :).
Table Structures:
Sample friends table structure
+--------------------------+-----------------------------+
| Field | Type |
+--------------------------+-----------------------------+
| user_id | int(10) |
| friend_id | int(10) |
| status | ENUM('pending','accepted') |
| user_id | int(10) |
+--------------------------+-----------------------------+
Sample notifications table structure
+--------------------------+---------------------+
| Field | Type |
+--------------------------+---------------------+
| id | int(10) |
| type | ENUM('pm','friend') |
| user_id | int(10) |
| from_id | int(10) |
+--------------------------+---------------------+
Sample private message table structure
+--------------------------+-----------------------+
| Field | Type |
+--------------------------+-----------------------+
| pm_id | int(12) |
| to_user | int(10) |
| from_user | int(10) |
| status | ENUM('read','unread') |
+--------------------------+-----------------------+
Sample users table structure
+--------------------------+---------------+
| Field | Type |
+--------------------------+---------------+
| id | int(10) |
| username | varchar(50) |
+--------------------------+---------------+
Your query mixes up unrelated things – a list of notifications, and a scalar set of counts. It also ties whether or not you get any results to the requirement to have at least one notification. From a design standpoint, these two should not be mixed, so I would re-write it as two queries.
You should use a correlated subquery for your counts:
The query for notifications is a simplified version of your original query: