如何列出表中的所有行并从多个与每行相关的表中计数?

时间:2014-07-13 20:07:09

标签: php mysql mysqli

我已经制作了Q& A网站,其中的问题可以包含标签,用户可以订阅他们想要的标签。所以,我已经为列出所有标签创建了标签页,并计算了所有订阅这些标签的问题和用户。我发现了类似的问题here,但对我来说更复杂。

下面的代码是我正在尝试的SQL,查询时间似乎很慢。我希望下面的SQL是使用JOIN/LEFT JOIN/RIGHT JOIN写的,我认为它会更快。但我不知道。我非常感谢您的帮助。

SQL

$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";

标签页

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

2 个答案:

答案 0 :(得分:1)

这是您的查询:

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;

这是一个合理的查询。您可能需要的是以下索引(如果您还没有它们):

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

您可能已经拥有了最后一个,因为id可能是tag表上的主键。

答案 1 :(得分:0)

在您发布的第二个查询中,您遗漏了SELECT,因此收到了发布的错误消息。您的第二个查询应如下所示

$sql = "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";

编辑:尝试使用带有SUM条件的CASE。由于您尚未显示表格结构或样本数据;不能肯定地说,但您可能想group by taggedquestion.ids喜欢

$sql = "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"