Reputation: 73
I'm trying to query information from two different tables, but I'm not figuring out how to do it best. As a disclaimer, I'm still learning MySQL/PHP, and I don't have control over the tables as they're set up - I'm trying to work with what I've got, since I can't add/change the tables. Below are the tables and the relevant attributes:
Table(attribute1, attribute2, ...);
------------------------------------
reports(id, reporter_id, added)
report_comments(comment_id, report_id, comment_text, commenter_id)
The reporter_id refers to the user who filed a report, and commenter_id is not the same person as reporter_id.
I want to get a count of how many report comments have, for example, the word "incorrect" in comment_text, for each reporter_id. I then want to make a table that shows each reporter's ID and the number of comments that are associated with that reporter's reports since "1383359439" (timestamp).
So far, I've not been very successful. My current query looks like this:
SELECT r.id, r.reporter_id,
(SELECT COUNT(*) FROM report_comments WHERE comment_text LIKE '%incorrect%' AND report_id = r.id) AS comments
FROM reports AS r
LEFT JOIN report_comments AS rc ON r.id = rc.report_id
WHERE r.added > 1383359439
GROUP BY r.reporter_id;
The resulting page, when I set the HTML table to list "reporter_id" followed by "comments", gives everyone who has filed a report since the time listed, but the count is either "0" or "1", with any reporter who has had "incorrect" in any report comment getting a "1" and those without "incorrect" getting "0":
Reporter1 | 0
Reporter2 | 1
Reporter3 | 0
Reporter4 | 1
Reporter5 | 1
The thing is, some reporters have had several comments with "incorrect" in them, and I want to get a count of each, and ONLY for those reporters (not ones who've never had an "incorrect" comment). For example:
Reporter2 | 2
Reporter4 | 17
Reporter5 | 3
I'm clearly missing something - what am I doing wrong?
Upvotes: 0
Views: 787
Reputation: 71384
You need to utilize grouping for this.
SELECT
r.reporter_id AS `reporter_id`,
COUNT(rc.report_id) AS `incorrect_count`
FROM reports AS r
INNER JOIN report_comments AS rc
ON r.id = rc.report_id
WHERE rc.comment_text LIKE '%incorrect%'
AND r.added > ?
GROUP BY `reporter_id`
Here ?
represents the timestamp you are trying to compare against.
To answer your follow-up question, there are a couple of ways to do this. I might suggest use of SUM()
in conjunction with CASE
like this:
SELECT
r.reporter_id AS `reporter_id`,
SUM(
CASE WHEN rc.comment_text LIKE '%incorrect%'
THEN 1
ELSE 0
END CASE
) AS `incorrect_count`,
SUM(
CASE WHEN rc.comment_text LIKE '%fake%'
THEN 2
ELSE 0
END CASE
) AS `fake_count`,
FROM reports AS r
INNER JOIN report_comments AS rc
ON r.id = rc.report_id
WHERE
rc.comment_text LIKE '%incorrect%'
OR rc.comment_text LIKE '%fake%'
AND r.added > ?
GROUP BY `reporter_id`
Upvotes: 2
Reputation: 57573
You could try
SELECT r.id, COUNT(c.id) tot
FROM reports r INNER JOIN report_comments
ON r.id = c.report_id
AND c.comment_text LIKE '%incorrect%'
AND r.added > 1383359439
GROUP BY r.reporter_id
Upvotes: 1
Reputation: 2770
It's something like this:
SELECT r.reporter_id, COUNT(*) comments
FROM reports AS r
INNER JOIN report_comments AS rc ON r.id = rc.report_id
WHERE r.added > 1383359439
AND comment_text LIKE '%incorrect%'
GROUP BY r.reporter_id;
I removed r.id since it doesn't make sense to have in this case as one reporter can have many reports (so multiple r.id).
Upvotes: 1