Reputation: 6029
I'm currently implementing blocking functionality into my web application. The user will have the option to block other users.
My current table set up is as follows:
CREATE TABLE [User].[Block_List]
(
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[UserId] [bigint] NOT NULL, -- Person that I have blocked
[BlockedById] [bigint] NOT NULL, -- Person who requested the block
[DateBlocked] [datetime] NOT NULL,
[DateUnblocked] [datetime] NULL
)
Now inside my stored procedure I'm joining this table to filter out the people that I've blocked as shown here:
SELECT
p.Id [SenderId],
p.Username,
COUNT(mr.RecipientId) [TotalMessages],
COUNT(CASE WHEN mr.ReadDate IS NULL THEN 1 END) AS [NewMessages],
up.PhotoId,
p.LastLoggedIn,
p.LoggedIn,
MAX(m.SentDate)[EmailDate]
FROM
[User].[User_Profile] p
JOIN
[MailBox].[Message] m ON p.Id = m.SenderId
JOIN
[MailBox].[MessageRecipient] mr ON m.Id = mr.MessageId
LEFT JOIN
[User].[User_Photos] up ON p.Id = up.UserId AND up.isProfilePic = 1
LEFT JOIN
[User].[Block_List] b ON p.Id = b.UserId
WHERE
mr.RecipientId = 1 --and mr.DeletedDate is null
AND (b.BlockedById = 1 and p.Id != b.UserId) -- Checking blocked table
GROUP BY
p.id, p.Username, mr.RecipientId, up.PhotoId, p.LastLoggedIn, p.LoggedIn
I have hard coded the BlockedbyId
to 1 as that's my current Id, unfortunately this doesn't return any rows when I would expect it to return at least one row, reason being I have two records and I've only blocked one of them.
When I execute the stored procedure above without the blocking where clause I get the following:
In my blocked table I have blocked the user with the Id of 2 as shown here:
When I add the blocking where clause back in I would expect to see the record for UserId 21 but unfortunately I don't get any records returned.
Any help would be great
Upvotes: 2
Views: 40
Reputation: 8743
The following part
LEFT JOIN [User].[Block_List] b on p.Id = b.UserId
WHERE mr.RecipientId = 1 --and mr.DeletedDate is null
AND (b.BlockedById = 1 and p.Id != b.UserId) -- Checking blocked table
should be replaced by
WHERE mr.RecipientId = 1
AND m.SenderId NOT IN (SELECT UserId FROM [User].[Block_List] WHERE BlockedById = 1)
Especially if you want to count I would be very careful when joining a table, because you might end up having too many combinations if not correctly filtered out afterwards, using the where clause when possible is safer in my opinion except if you really want to join and use the values.
Upvotes: 1
Reputation: 118957
You have some mutually exclusive conditions set here. Your join says
p.Id = b.UserId
However the where clause also says
p.Id != b.UserId
So when you combine them you will get no rows.
Upvotes: 1