简体   繁体   中英

How can I get a row with along the number of all related rows?

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:

  1. the title of one row (for given id)
  2. the number of its related rows
  3. the number of its votes

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?

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM