简体   繁体   中英

How can I list all rows in table and count from multiple table that related with each rows?

I have made Q & A website that a questions can have tags in it and the user can subscribe to tags they want. So, I have create tag page for list all tags and count all questions and users who subscribed to these tags.I found similar question here but it more complex for me.
The code below is SQL I'm trying and it seems very slow for query times. I want SQL below is to write by using JOIN/LEFT JOIN/RIGHT JOIN I think it will be faster. But I have no idea.

SQL

select tag.*,
    (select count(*) from taggedquestion where taggedquestion.tagid = tag.id) questionCount, 
    (select count(*) from tagsubscription where tagsubscription.tagid = tag.id) userCount 
from tag order by tag.id asc

Tags page

 Tag name             question count         user count
----------------------------------------------------------------
 computer               12                      5
 science                10                      3
 travel                 6                       2
 programing             18                      3
 ...                    ...                     ...
 ...                    ...                     ...

This is your query:

select tag.*,
       (select count(*) from taggedquestion where taggedquestion.tagid = tag.id and ids = '0'
       ) as questionCount, 
       (select count(*) from tagsubscription where tagsubscription.tagid = tag.id and ids = '0'
       ) as userCount 
from tag
order by tag.id asc;

This is a reasonable query. Probably what you need for performance are the following indexes (if you don't already have them):

taggedquestion(tagid, ids)
tagsubscription(tagid, ids)
tag(id)

You probably already have the last one, because id is presumably a primary key on the tag table.

On your second posted query, you are missing SELECT and so getting the posted error. Your second query should look like below

SELECT tag.*, 
( SELECT COUNT(*) FROM taggedquestion
 LEFT JOIN tag ON tag.id = taggedquestion.tagid 
 and taggedquestion.ids = '0') AS postCount, 
(SELECT COUNT(*) FROM tagsubscription
 LEFT JOIN tag ON tag.id = tagsubscription.tagid 
 and tagsubscription.ids = '0') AS userCount 
 FROM tag

Try like this then using SUM with CASE condition. Since you haven't shown your tables structure or sample data; can't say for sure but you might want to group by the taggedquestion.ids like

SELECT tag.*, 
( SELECT SUM(CASE WHEN taggedquestion.ids = '0' THEN 1 ELSE 0 END) 
 FROM taggedquestion
 INNER JOIN tag 
 ON tag.id = taggedquestion.tagid 
 GROUP BY taggedquestion.ids) AS postCount, 
(SELECT SUM(CASE WHEN tagsubscription.ids = '0' THEN 1 ELSE 0 END) 
 FROM tagsubscription
 INNER JOIN tag 
 ON tag.id = tagsubscription.tagid 
 GROUP BY tagsubscription.ids) AS userCount 
 FROM tag

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