Reputation: 10218
I have a table structure like this:
// question_and_answer
+----+-----------+------------+
| id | title | related_id |
+----+-----------+------------+
| 1 | q1 | NULL |
| 2 | | 1 |
| 3 | | 1 |
| 4 | q2 | NULL |
| 5 | | 1 |
| 6 | | 4 |
| 7 | | 1 |
| 8 | q3 | NULL |
| 9 | | 8 |
| 10 | | 4 |
+----+-----------+------------+
// votes
+----+---------+
| id | post_id |
+----+---------+
| 1 | 2 |
| 2 | 2 |
| 3 | 1 |
| 4 | 6 |
| 5 | 2 |
| 6 | 1 |
| 7 | 8 |
+----+---------+
I need to get three things:
I can get them by three separated queries:
// Assuming id = 1
SELECT title FROM question_and_answer WHERE id = 1;
SELECT count(a.*) FROM question_and_answer q
LEFT JOIN question_and_answer a ON q.id = a.related_id WHERE q.id = 1;
SELECT count(v.*) FROM question_and_answer qa
LEFT JOIN votes v on qa.id = v.post_id
WHERE qa.id = 1;
The expected result is this:
// Assuming id = 1
+-------+-------------+-----------+
| title | answers_num | votes_num |
+-------+-------------|-----------+
| q1 | 4 | 2 |
+-------+-------------+-----------+
// Assuming id = 2
+-------+-------------+-----------+
| title | answers_num | votes_num |
+-------+-------------|-----------+
| | 0 | 3 |
+-------+-------------+-----------+
Any idea how can I get that using one query?
Upvotes: 1
Views: 35
Reputation: 133360
For obtain the number of rows with not null values you could use count and left join For single id eg: 1
SELECT qa.title, t1.answers_num, t2.votes_num
FROM question_and_answer qa
LEFT JOIN (
SELECT qa.title, count(c.related_id) answers_num
FROM question_and_answer qa
LEFT JOIN question_and_answer c ON qa.id = c.related_id
GROUP BY qa.title
) t1 on t1.title = qa.title
LEFT JOIN (
SELECT qa.title, count(v.post_id) votes_num
FROM question_and_answer qa
LEFT JOIN votes v on qa.id = v.post_id
GROUP BY qa.title
) t2 ON t2.title = qa.title
WHERE qa.id = 1;
For all the id
SELECT qa.title, t1.answers_num, t2.votes_num
FROM question_and_answer qa
LEFT JOIN (
SELECT qa.title, count(c.related_id) answers_num
FROM question_and_answer qa
LEFT JOIN question_and_answer c ON qa.id = c.related_id
) t1 on t1.title = qa.title
LEFT JOIN (
SELECT qa.title, count(v.post_id) votes_num
FROM question_and_answer qa
LEFT JOIN votes v on qa.id = v.post_id
) t2 ON t2.title = qa.title
for obatin the count of distinct not null value you could use
For single id eg: 1
SELECT qa.title, c.count(distinct related_id) answers_num
, v.count(distinct post_id) votes_num
FROM question_and_answer qa
LEFT JOIN question_and_answer c ON qa.id = c.related_id
LEFT JOIN votes v on qa.id = v.post_id
WHERE qa.id = 1;
For all the id
SELECT qa.title, c.count(distinct related_id) answers_num
, v.count(distinct post_id) votes_num
FROM question_and_answer qa
LEFT JOIN question_and_answer c ON qa.id = c.related_id
LEFT JOIN votes v on qa.id = v.post_id
WHERE related_id is null
group by qa.title;
Upvotes: 1