开发者

MySql correlated subquery count across tables

开发者 https://www.devze.com 2023-03-20 05:47 出处:网络
I have 3 tables that are related with the fields below: forumstopicsposts f_id ---- f_idt_id ---- t_idp_id

I have 3 tables that are related with the fields below:

forums          topics          posts
    f_id ---- f_id  t_id ---- t_id  p_id    

For a given f_id I'm trying to 2 different counts in 1 query:

  1. the total numbers of t_id (topics)
  2. the total numbers of p_id (posts)

for example f_id=78 should simply result to

tc  |  pc
---------
4   |  3

Meaning there are 4 topics and a total of 3 post to those topics, all in that forum. But when I use this simple query (which is after hours of trying and research my best attempt):

SELECT (
SELECT COUNT( t_id ) 
FROM topics
WHERE f_id =  '78'
) AS tc, (

SELECT COUNT( p_id ) 
FROM posts
WHERE posts.t_id = topics.t_id
) AS pc
FROM to开发者_如何转开发pics
WHERE topics.f_id =  '78'

But this only results to a count for each row in topics that matches the f_id like this:

tc  |  pc
---------
4   |  0
4   |  1
4   |  2
4   |  0

and not a total count. I'm genuinely stuck here, even though I was pretty sure this was not a hard thing to achieve. Thanks!


Edit: as requested a bit of sample data:

forums

f_id  t_name      ...
---------------------
78    Test        ...
33    Something   ...

topics

f_id  t_id   t_date      ...
----------------------------
78    28     2011-07-14  ...
78    53     2011-07-14  ...
78    54     2011-07-14  ...
78    56     2011-07-14  ...
33    57     2011-07-14  ...

posts

t_id  p_id  p_date      ...
---------------------------
54    2     2011-07-14  ...
54    4     2011-07-14  ...
53    5     2011-07-14  ...


It is common to store precalculated values of posts and threads directly in topics and forums tables accordingly, since counting (probably with distinction) is not a cheap operation.

After creating you can maintain that counters with triggers or your code.


Use count(distinct column) to count the number of different values for a column:

select
    f.f_id,
    count(distinct t.t_id) as tc,
    count(distinct p.p_id) as pc
from forums f
join topics t on t.f_id = f.f_id
join posts p on p.t_id = t.t_id
group by f.f_id;  -- edited. initial answer had this group by omitted


I seem to have found the following solution that actually mixes both @Bohemian 's query with my original one and seems to work well. I'm not sure if this is the optimal way to achieve though.

SELECT f.f_id, (SELECT COUNT(t.t_id) 
                FROM topics t
                WHERE t.f_id =  f.f_id) AS tc, 

                COUNT(distinct p.p_id) AS pc

FROM forums f
JOIN topics t ON t.f_id = f.f_id
JOIN posts p ON p.t_id = t.t_id

WHERE f.f_id = 78
GROUP BY f.f_id;
0

精彩评论

暂无评论...
验证码 换一张
取 消