When no records exists, should return non-zero for unread messages count
This is my table structure:
tblTickets
ticket_id | subject | creator_id | created_date | last_updated | category_id | ticket_status
tblMessages
msg_id | msg | ticket_id | replied_by | reply_time
tblReadBy - PrimaryKey: (ticket_id,user_id)
ticket_id | user_id | last_read_time
Am trying to list all the tickets to the currently logged in User. That is, tickets that were created by them only.
Also, am showing a small color indication to let the the User know whether there's any unread messages.
So, whenever a User views a Ticket(by clicking from the list), a record will be either inserted/updated in tblReadBy with the ticket_id and user_id along with the current time)
My query for listing Tickets looks somewhat like this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT COUNT(*)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Here, XXX is the user_id of the currently logged in User. This query works fine if there's a row in tblReadBy table for the currently logged in user_id and the ticket_id.
But if there's no row exists for this user_id and ticket_id, then as per logic it's an "unread ticket", but the query would return 0 for has_unread_msg column.
How can I fix this particular case?
NOTE: There would be more than one user replying to a Ticket. Like the actual User, Moderator (more than one), Admin, etc.
Thank you
SOLUTION:
So far, what I figured out is this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
COALESCE(SUM(CASE WHEN `last_read_time` < t.`last_updated` THEN 1 ELSE 0 END), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX'
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Am still trying to test all possible cases.
mysql
add a comment |
This is my table structure:
tblTickets
ticket_id | subject | creator_id | created_date | last_updated | category_id | ticket_status
tblMessages
msg_id | msg | ticket_id | replied_by | reply_time
tblReadBy - PrimaryKey: (ticket_id,user_id)
ticket_id | user_id | last_read_time
Am trying to list all the tickets to the currently logged in User. That is, tickets that were created by them only.
Also, am showing a small color indication to let the the User know whether there's any unread messages.
So, whenever a User views a Ticket(by clicking from the list), a record will be either inserted/updated in tblReadBy with the ticket_id and user_id along with the current time)
My query for listing Tickets looks somewhat like this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT COUNT(*)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Here, XXX is the user_id of the currently logged in User. This query works fine if there's a row in tblReadBy table for the currently logged in user_id and the ticket_id.
But if there's no row exists for this user_id and ticket_id, then as per logic it's an "unread ticket", but the query would return 0 for has_unread_msg column.
How can I fix this particular case?
NOTE: There would be more than one user replying to a Ticket. Like the actual User, Moderator (more than one), Admin, etc.
Thank you
SOLUTION:
So far, what I figured out is this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
COALESCE(SUM(CASE WHEN `last_read_time` < t.`last_updated` THEN 1 ELSE 0 END), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX'
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Am still trying to test all possible cases.
mysql
Your unread_msg_count does not make sense. Instead it should be times_ticket_is_read
– Madhur Bhaiya
Nov 11 at 13:19
@MadhurBhaiya, like I said earlier,unread_msg_countwill work as expected if there's any records for the currently logged inuser_idand theticket_id. But if there's no records, then the logic will fail! There will be more than one person replying to the ticket. Like a User, Admin and Moderator.
– Vpp Man
Nov 11 at 13:23
As I understand from your table definition and current query, unread_msg_count is basically counting the number of times the use XXX has read this ticket before the ticket has been updated.tblReadByhas only one row for a combination ofuser_idandticket_id??
– Madhur Bhaiya
Nov 11 at 13:28
@MadhurBhaiya, you can read that column name ashas_unread_msginstead ofunread_msg_count.
– Vpp Man
Nov 11 at 13:31
@MadhurBhaiya, I already mentioned that a row intblReadBywill be either inserted/updated when a User view Ticket (there's separateINSERT .. ON DUPLICATE UPDATE...query behind the scenes, which I didn't posted as it is irrelevant.
– Vpp Man
Nov 11 at 13:35
add a comment |
This is my table structure:
tblTickets
ticket_id | subject | creator_id | created_date | last_updated | category_id | ticket_status
tblMessages
msg_id | msg | ticket_id | replied_by | reply_time
tblReadBy - PrimaryKey: (ticket_id,user_id)
ticket_id | user_id | last_read_time
Am trying to list all the tickets to the currently logged in User. That is, tickets that were created by them only.
Also, am showing a small color indication to let the the User know whether there's any unread messages.
So, whenever a User views a Ticket(by clicking from the list), a record will be either inserted/updated in tblReadBy with the ticket_id and user_id along with the current time)
My query for listing Tickets looks somewhat like this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT COUNT(*)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Here, XXX is the user_id of the currently logged in User. This query works fine if there's a row in tblReadBy table for the currently logged in user_id and the ticket_id.
But if there's no row exists for this user_id and ticket_id, then as per logic it's an "unread ticket", but the query would return 0 for has_unread_msg column.
How can I fix this particular case?
NOTE: There would be more than one user replying to a Ticket. Like the actual User, Moderator (more than one), Admin, etc.
Thank you
SOLUTION:
So far, what I figured out is this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
COALESCE(SUM(CASE WHEN `last_read_time` < t.`last_updated` THEN 1 ELSE 0 END), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX'
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Am still trying to test all possible cases.
mysql
This is my table structure:
tblTickets
ticket_id | subject | creator_id | created_date | last_updated | category_id | ticket_status
tblMessages
msg_id | msg | ticket_id | replied_by | reply_time
tblReadBy - PrimaryKey: (ticket_id,user_id)
ticket_id | user_id | last_read_time
Am trying to list all the tickets to the currently logged in User. That is, tickets that were created by them only.
Also, am showing a small color indication to let the the User know whether there's any unread messages.
So, whenever a User views a Ticket(by clicking from the list), a record will be either inserted/updated in tblReadBy with the ticket_id and user_id along with the current time)
My query for listing Tickets looks somewhat like this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT COUNT(*)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Here, XXX is the user_id of the currently logged in User. This query works fine if there's a row in tblReadBy table for the currently logged in user_id and the ticket_id.
But if there's no row exists for this user_id and ticket_id, then as per logic it's an "unread ticket", but the query would return 0 for has_unread_msg column.
How can I fix this particular case?
NOTE: There would be more than one user replying to a Ticket. Like the actual User, Moderator (more than one), Admin, etc.
Thank you
SOLUTION:
So far, what I figured out is this:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
COALESCE(SUM(CASE WHEN `last_read_time` < t.`last_updated` THEN 1 ELSE 0 END), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX'
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
Am still trying to test all possible cases.
mysql
mysql
edited Nov 11 at 14:20
asked Nov 11 at 13:05
Vpp Man
81142453
81142453
Your unread_msg_count does not make sense. Instead it should be times_ticket_is_read
– Madhur Bhaiya
Nov 11 at 13:19
@MadhurBhaiya, like I said earlier,unread_msg_countwill work as expected if there's any records for the currently logged inuser_idand theticket_id. But if there's no records, then the logic will fail! There will be more than one person replying to the ticket. Like a User, Admin and Moderator.
– Vpp Man
Nov 11 at 13:23
As I understand from your table definition and current query, unread_msg_count is basically counting the number of times the use XXX has read this ticket before the ticket has been updated.tblReadByhas only one row for a combination ofuser_idandticket_id??
– Madhur Bhaiya
Nov 11 at 13:28
@MadhurBhaiya, you can read that column name ashas_unread_msginstead ofunread_msg_count.
– Vpp Man
Nov 11 at 13:31
@MadhurBhaiya, I already mentioned that a row intblReadBywill be either inserted/updated when a User view Ticket (there's separateINSERT .. ON DUPLICATE UPDATE...query behind the scenes, which I didn't posted as it is irrelevant.
– Vpp Man
Nov 11 at 13:35
add a comment |
Your unread_msg_count does not make sense. Instead it should be times_ticket_is_read
– Madhur Bhaiya
Nov 11 at 13:19
@MadhurBhaiya, like I said earlier,unread_msg_countwill work as expected if there's any records for the currently logged inuser_idand theticket_id. But if there's no records, then the logic will fail! There will be more than one person replying to the ticket. Like a User, Admin and Moderator.
– Vpp Man
Nov 11 at 13:23
As I understand from your table definition and current query, unread_msg_count is basically counting the number of times the use XXX has read this ticket before the ticket has been updated.tblReadByhas only one row for a combination ofuser_idandticket_id??
– Madhur Bhaiya
Nov 11 at 13:28
@MadhurBhaiya, you can read that column name ashas_unread_msginstead ofunread_msg_count.
– Vpp Man
Nov 11 at 13:31
@MadhurBhaiya, I already mentioned that a row intblReadBywill be either inserted/updated when a User view Ticket (there's separateINSERT .. ON DUPLICATE UPDATE...query behind the scenes, which I didn't posted as it is irrelevant.
– Vpp Man
Nov 11 at 13:35
Your unread_msg_count does not make sense. Instead it should be times_ticket_is_read
– Madhur Bhaiya
Nov 11 at 13:19
Your unread_msg_count does not make sense. Instead it should be times_ticket_is_read
– Madhur Bhaiya
Nov 11 at 13:19
@MadhurBhaiya, like I said earlier,
unread_msg_count will work as expected if there's any records for the currently logged in user_id and the ticket_id. But if there's no records, then the logic will fail! There will be more than one person replying to the ticket. Like a User, Admin and Moderator.– Vpp Man
Nov 11 at 13:23
@MadhurBhaiya, like I said earlier,
unread_msg_count will work as expected if there's any records for the currently logged in user_id and the ticket_id. But if there's no records, then the logic will fail! There will be more than one person replying to the ticket. Like a User, Admin and Moderator.– Vpp Man
Nov 11 at 13:23
As I understand from your table definition and current query, unread_msg_count is basically counting the number of times the use XXX has read this ticket before the ticket has been updated.
tblReadBy has only one row for a combination of user_id and ticket_id ??– Madhur Bhaiya
Nov 11 at 13:28
As I understand from your table definition and current query, unread_msg_count is basically counting the number of times the use XXX has read this ticket before the ticket has been updated.
tblReadBy has only one row for a combination of user_id and ticket_id ??– Madhur Bhaiya
Nov 11 at 13:28
@MadhurBhaiya, you can read that column name as
has_unread_msg instead of unread_msg_count.– Vpp Man
Nov 11 at 13:31
@MadhurBhaiya, you can read that column name as
has_unread_msg instead of unread_msg_count.– Vpp Man
Nov 11 at 13:31
@MadhurBhaiya, I already mentioned that a row in
tblReadBy will be either inserted/updated when a User view Ticket (there's separate INSERT .. ON DUPLICATE UPDATE... query behind the scenes, which I didn't posted as it is irrelevant.– Vpp Man
Nov 11 at 13:35
@MadhurBhaiya, I already mentioned that a row in
tblReadBy will be either inserted/updated when a User view Ticket (there's separate INSERT .. ON DUPLICATE UPDATE... query behind the scenes, which I didn't posted as it is irrelevant.– Vpp Man
Nov 11 at 13:35
add a comment |
3 Answers
3
active
oldest
votes
We can use SUM() function's NULL handling behavior. It will return NULL if no row exists.
If the return set has no rows, SUM() returns NULL
MySQL automatically typecasts results of a Boolean comparison operator to 0/1. Using this behavior, we can can use Sum() and Coalesce().
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
-- coalesce handles case when no rows
SELECT COALESCE(SUM(`ticket_id` > 0), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
Bhauya, this is what seems to be working:SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'
– Vpp Man
Nov 11 at 14:24
@VppMan replaceCOALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1)withCOALESCE(SUM(ticket_id IS NOT NULL), 1)
– Madhur Bhaiya
Nov 11 at 14:25
I don't think what you suggested will work. Because in the WHERE conditionlast_read_time < t.last_updatedis used. Which will fetch only those rows that matches that condition! So usingSUM()on those rows again breaks the logic!
– Vpp Man
Nov 11 at 14:35
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
|
show 2 more comments
As I see it you need to count both messages that has been update in tblReadBy and messages that are new and have never been read, that is they exists in tblTickets but not in tblReadBy.
Here is my solution that is a bit complicated, I would love to see someone improve it, but basically I join agains two `SELECT ... COUNT(*)´, one for completely new messages and one for updated
SELECT t.ticket_id, subject, t.user_id, created_date, last_updated, IFNULL(c1.count, 0) + IFNULL(c2.count, 0)
FROM tblTickets t
LEFT JOIN (SELECT ticket_id, user_id, COUNT(*) count
FROM tblTickets t
WHERE NOT EXISTS (SELECT *
FROM tblReadBy r
WHERE t.ticket_id = r.ticket_id
AND t.user_id = r.user_id)
GROUP BY ticket_id, user_id) AS c1 ON c1.ticket_id = t.ticket_id AND c1.user_id = t.user_id
LEFT JOIN (SELECT r.ticket_id, r.user_id, COUNT(*) count
FROM tblReadBy r
JOIN tblTickets t ON t.ticket_id = r.ticket_id AND t.user_id = r.user_id
WHERE r.last_read_time < t.last_updated
GROUP BY r.ticket_id, r.user_id) AS c2 ON c2.ticket_id = t.ticket_id AND c2.user_id = t.user_id
WHERE t.user_id = 'aaa'
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
add a comment |
This could work because it left joins the two tables to find out whether there are any records in tblReadBy and then uses the result in the subquery. Unfortunately I couldn't test it.
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
You might need to add r.ticket_id in the SELECT list of the outer query like so:
SELECT
t.`ticket_id`,
r.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket intblReadBy(because there will be more than one person replying to the same Ticket). So I added aGROUP BY t.ticket_idin the outer query. Its okay right?
– Vpp Man
Nov 11 at 14:03
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249022%2fwhen-no-records-exists-should-return-non-zero-for-unread-messages-count%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
We can use SUM() function's NULL handling behavior. It will return NULL if no row exists.
If the return set has no rows, SUM() returns NULL
MySQL automatically typecasts results of a Boolean comparison operator to 0/1. Using this behavior, we can can use Sum() and Coalesce().
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
-- coalesce handles case when no rows
SELECT COALESCE(SUM(`ticket_id` > 0), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
Bhauya, this is what seems to be working:SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'
– Vpp Man
Nov 11 at 14:24
@VppMan replaceCOALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1)withCOALESCE(SUM(ticket_id IS NOT NULL), 1)
– Madhur Bhaiya
Nov 11 at 14:25
I don't think what you suggested will work. Because in the WHERE conditionlast_read_time < t.last_updatedis used. Which will fetch only those rows that matches that condition! So usingSUM()on those rows again breaks the logic!
– Vpp Man
Nov 11 at 14:35
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
|
show 2 more comments
We can use SUM() function's NULL handling behavior. It will return NULL if no row exists.
If the return set has no rows, SUM() returns NULL
MySQL automatically typecasts results of a Boolean comparison operator to 0/1. Using this behavior, we can can use Sum() and Coalesce().
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
-- coalesce handles case when no rows
SELECT COALESCE(SUM(`ticket_id` > 0), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
Bhauya, this is what seems to be working:SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'
– Vpp Man
Nov 11 at 14:24
@VppMan replaceCOALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1)withCOALESCE(SUM(ticket_id IS NOT NULL), 1)
– Madhur Bhaiya
Nov 11 at 14:25
I don't think what you suggested will work. Because in the WHERE conditionlast_read_time < t.last_updatedis used. Which will fetch only those rows that matches that condition! So usingSUM()on those rows again breaks the logic!
– Vpp Man
Nov 11 at 14:35
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
|
show 2 more comments
We can use SUM() function's NULL handling behavior. It will return NULL if no row exists.
If the return set has no rows, SUM() returns NULL
MySQL automatically typecasts results of a Boolean comparison operator to 0/1. Using this behavior, we can can use Sum() and Coalesce().
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
-- coalesce handles case when no rows
SELECT COALESCE(SUM(`ticket_id` > 0), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
We can use SUM() function's NULL handling behavior. It will return NULL if no row exists.
If the return set has no rows, SUM() returns NULL
MySQL automatically typecasts results of a Boolean comparison operator to 0/1. Using this behavior, we can can use Sum() and Coalesce().
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
-- coalesce handles case when no rows
SELECT COALESCE(SUM(`ticket_id` > 0), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
edited Nov 11 at 14:27
answered Nov 11 at 13:15
Madhur Bhaiya
19.5k62236
19.5k62236
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
Bhauya, this is what seems to be working:SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'
– Vpp Man
Nov 11 at 14:24
@VppMan replaceCOALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1)withCOALESCE(SUM(ticket_id IS NOT NULL), 1)
– Madhur Bhaiya
Nov 11 at 14:25
I don't think what you suggested will work. Because in the WHERE conditionlast_read_time < t.last_updatedis used. Which will fetch only those rows that matches that condition! So usingSUM()on those rows again breaks the logic!
– Vpp Man
Nov 11 at 14:35
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
|
show 2 more comments
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
Bhauya, this is what seems to be working:SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'
– Vpp Man
Nov 11 at 14:24
@VppMan replaceCOALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1)withCOALESCE(SUM(ticket_id IS NOT NULL), 1)
– Madhur Bhaiya
Nov 11 at 14:25
I don't think what you suggested will work. Because in the WHERE conditionlast_read_time < t.last_updatedis used. Which will fetch only those rows that matches that condition! So usingSUM()on those rows again breaks the logic!
– Vpp Man
Nov 11 at 14:35
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
@VppMan check the updated answer; use the part below the horizontal line
– Madhur Bhaiya
Nov 11 at 14:06
Bhauya, this is what seems to be working:
SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'– Vpp Man
Nov 11 at 14:24
Bhauya, this is what seems to be working:
SELECT COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) FROM tblReadBy WHERE ticket_id = t.ticket_id AND user_id = 'XXX'– Vpp Man
Nov 11 at 14:24
@VppMan replace
COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) with COALESCE(SUM(ticket_id IS NOT NULL), 1)– Madhur Bhaiya
Nov 11 at 14:25
@VppMan replace
COALESCE(SUM(CASE WHEN last_read_time < t.last_updated THEN 1 ELSE 0 END), 1) with COALESCE(SUM(ticket_id IS NOT NULL), 1)– Madhur Bhaiya
Nov 11 at 14:25
I don't think what you suggested will work. Because in the WHERE condition
last_read_time < t.last_updated is used. Which will fetch only those rows that matches that condition! So using SUM() on those rows again breaks the logic!– Vpp Man
Nov 11 at 14:35
I don't think what you suggested will work. Because in the WHERE condition
last_read_time < t.last_updated is used. Which will fetch only those rows that matches that condition! So using SUM() on those rows again breaks the logic!– Vpp Man
Nov 11 at 14:35
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
@VppMan have you tried my code ? Can you create a fiddle to prove the same. Based on my understanding, my solution should work.
– Madhur Bhaiya
Nov 11 at 14:37
|
show 2 more comments
As I see it you need to count both messages that has been update in tblReadBy and messages that are new and have never been read, that is they exists in tblTickets but not in tblReadBy.
Here is my solution that is a bit complicated, I would love to see someone improve it, but basically I join agains two `SELECT ... COUNT(*)´, one for completely new messages and one for updated
SELECT t.ticket_id, subject, t.user_id, created_date, last_updated, IFNULL(c1.count, 0) + IFNULL(c2.count, 0)
FROM tblTickets t
LEFT JOIN (SELECT ticket_id, user_id, COUNT(*) count
FROM tblTickets t
WHERE NOT EXISTS (SELECT *
FROM tblReadBy r
WHERE t.ticket_id = r.ticket_id
AND t.user_id = r.user_id)
GROUP BY ticket_id, user_id) AS c1 ON c1.ticket_id = t.ticket_id AND c1.user_id = t.user_id
LEFT JOIN (SELECT r.ticket_id, r.user_id, COUNT(*) count
FROM tblReadBy r
JOIN tblTickets t ON t.ticket_id = r.ticket_id AND t.user_id = r.user_id
WHERE r.last_read_time < t.last_updated
GROUP BY r.ticket_id, r.user_id) AS c2 ON c2.ticket_id = t.ticket_id AND c2.user_id = t.user_id
WHERE t.user_id = 'aaa'
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
add a comment |
As I see it you need to count both messages that has been update in tblReadBy and messages that are new and have never been read, that is they exists in tblTickets but not in tblReadBy.
Here is my solution that is a bit complicated, I would love to see someone improve it, but basically I join agains two `SELECT ... COUNT(*)´, one for completely new messages and one for updated
SELECT t.ticket_id, subject, t.user_id, created_date, last_updated, IFNULL(c1.count, 0) + IFNULL(c2.count, 0)
FROM tblTickets t
LEFT JOIN (SELECT ticket_id, user_id, COUNT(*) count
FROM tblTickets t
WHERE NOT EXISTS (SELECT *
FROM tblReadBy r
WHERE t.ticket_id = r.ticket_id
AND t.user_id = r.user_id)
GROUP BY ticket_id, user_id) AS c1 ON c1.ticket_id = t.ticket_id AND c1.user_id = t.user_id
LEFT JOIN (SELECT r.ticket_id, r.user_id, COUNT(*) count
FROM tblReadBy r
JOIN tblTickets t ON t.ticket_id = r.ticket_id AND t.user_id = r.user_id
WHERE r.last_read_time < t.last_updated
GROUP BY r.ticket_id, r.user_id) AS c2 ON c2.ticket_id = t.ticket_id AND c2.user_id = t.user_id
WHERE t.user_id = 'aaa'
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
add a comment |
As I see it you need to count both messages that has been update in tblReadBy and messages that are new and have never been read, that is they exists in tblTickets but not in tblReadBy.
Here is my solution that is a bit complicated, I would love to see someone improve it, but basically I join agains two `SELECT ... COUNT(*)´, one for completely new messages and one for updated
SELECT t.ticket_id, subject, t.user_id, created_date, last_updated, IFNULL(c1.count, 0) + IFNULL(c2.count, 0)
FROM tblTickets t
LEFT JOIN (SELECT ticket_id, user_id, COUNT(*) count
FROM tblTickets t
WHERE NOT EXISTS (SELECT *
FROM tblReadBy r
WHERE t.ticket_id = r.ticket_id
AND t.user_id = r.user_id)
GROUP BY ticket_id, user_id) AS c1 ON c1.ticket_id = t.ticket_id AND c1.user_id = t.user_id
LEFT JOIN (SELECT r.ticket_id, r.user_id, COUNT(*) count
FROM tblReadBy r
JOIN tblTickets t ON t.ticket_id = r.ticket_id AND t.user_id = r.user_id
WHERE r.last_read_time < t.last_updated
GROUP BY r.ticket_id, r.user_id) AS c2 ON c2.ticket_id = t.ticket_id AND c2.user_id = t.user_id
WHERE t.user_id = 'aaa'
As I see it you need to count both messages that has been update in tblReadBy and messages that are new and have never been read, that is they exists in tblTickets but not in tblReadBy.
Here is my solution that is a bit complicated, I would love to see someone improve it, but basically I join agains two `SELECT ... COUNT(*)´, one for completely new messages and one for updated
SELECT t.ticket_id, subject, t.user_id, created_date, last_updated, IFNULL(c1.count, 0) + IFNULL(c2.count, 0)
FROM tblTickets t
LEFT JOIN (SELECT ticket_id, user_id, COUNT(*) count
FROM tblTickets t
WHERE NOT EXISTS (SELECT *
FROM tblReadBy r
WHERE t.ticket_id = r.ticket_id
AND t.user_id = r.user_id)
GROUP BY ticket_id, user_id) AS c1 ON c1.ticket_id = t.ticket_id AND c1.user_id = t.user_id
LEFT JOIN (SELECT r.ticket_id, r.user_id, COUNT(*) count
FROM tblReadBy r
JOIN tblTickets t ON t.ticket_id = r.ticket_id AND t.user_id = r.user_id
WHERE r.last_read_time < t.last_updated
GROUP BY r.ticket_id, r.user_id) AS c2 ON c2.ticket_id = t.ticket_id AND c2.user_id = t.user_id
WHERE t.user_id = 'aaa'
answered Nov 11 at 14:11
Joakim Danielson
6,6833623
6,6833623
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
add a comment |
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
Thank you. It looks a bit complex. Am trying to understand the idea from your query first.
– Vpp Man
Nov 11 at 14:33
add a comment |
This could work because it left joins the two tables to find out whether there are any records in tblReadBy and then uses the result in the subquery. Unfortunately I couldn't test it.
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
You might need to add r.ticket_id in the SELECT list of the outer query like so:
SELECT
t.`ticket_id`,
r.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket intblReadBy(because there will be more than one person replying to the same Ticket). So I added aGROUP BY t.ticket_idin the outer query. Its okay right?
– Vpp Man
Nov 11 at 14:03
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
add a comment |
This could work because it left joins the two tables to find out whether there are any records in tblReadBy and then uses the result in the subquery. Unfortunately I couldn't test it.
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
You might need to add r.ticket_id in the SELECT list of the outer query like so:
SELECT
t.`ticket_id`,
r.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket intblReadBy(because there will be more than one person replying to the same Ticket). So I added aGROUP BY t.ticket_idin the outer query. Its okay right?
– Vpp Man
Nov 11 at 14:03
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
add a comment |
This could work because it left joins the two tables to find out whether there are any records in tblReadBy and then uses the result in the subquery. Unfortunately I couldn't test it.
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
You might need to add r.ticket_id in the SELECT list of the outer query like so:
SELECT
t.`ticket_id`,
r.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
This could work because it left joins the two tables to find out whether there are any records in tblReadBy and then uses the result in the subquery. Unfortunately I couldn't test it.
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
You might need to add r.ticket_id in the SELECT list of the outer query like so:
SELECT
t.`ticket_id`,
r.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
edited Nov 11 at 14:42
answered Nov 11 at 13:34
rf1234
40257
40257
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket intblReadBy(because there will be more than one person replying to the same Ticket). So I added aGROUP BY t.ticket_idin the outer query. Its okay right?
– Vpp Man
Nov 11 at 14:03
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
add a comment |
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket intblReadBy(because there will be more than one person replying to the same Ticket). So I added aGROUP BY t.ticket_idin the outer query. Its okay right?
– Vpp Man
Nov 11 at 14:03
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket in
tblReadBy (because there will be more than one person replying to the same Ticket). So I added a GROUP BY t.ticket_id in the outer query. Its okay right?– Vpp Man
Nov 11 at 14:03
thank you. It worked! But it will give duplicate records if there's more than one rows for the same Ticket in
tblReadBy (because there will be more than one person replying to the same Ticket). So I added a GROUP BY t.ticket_id in the outer query. Its okay right?– Vpp Man
Nov 11 at 14:03
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
ok, got it. I modified the LEFT JOIN to only select tickets from the respective user (if any) or to return NULL if there aren't any.
– rf1234
Nov 11 at 14:40
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249022%2fwhen-no-records-exists-should-return-non-zero-for-unread-messages-count%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Your unread_msg_count does not make sense. Instead it should be times_ticket_is_read
– Madhur Bhaiya
Nov 11 at 13:19
@MadhurBhaiya, like I said earlier,
unread_msg_countwill work as expected if there's any records for the currently logged inuser_idand theticket_id. But if there's no records, then the logic will fail! There will be more than one person replying to the ticket. Like a User, Admin and Moderator.– Vpp Man
Nov 11 at 13:23
As I understand from your table definition and current query, unread_msg_count is basically counting the number of times the use XXX has read this ticket before the ticket has been updated.
tblReadByhas only one row for a combination ofuser_idandticket_id??– Madhur Bhaiya
Nov 11 at 13:28
@MadhurBhaiya, you can read that column name as
has_unread_msginstead ofunread_msg_count.– Vpp Man
Nov 11 at 13:31
@MadhurBhaiya, I already mentioned that a row in
tblReadBywill be either inserted/updated when a User view Ticket (there's separateINSERT .. ON DUPLICATE UPDATE...query behind the scenes, which I didn't posted as it is irrelevant.– Vpp Man
Nov 11 at 13:35