2014-07-08 38 views
1

我试图获得一个SQL查询来给我一个count的结果,但是我需要结果来包含count为0的行。找到解决这个问题的方法是使用IFNULL(COUNT(*), 0)代替COUNT(*),但对结果没有影响。我也尝试过使用LEFT JOIN,但是如果我试图放入这些语句,SQL给了我一个语法错误。这是我的表设置获取SQL查询以在3个表中为null计数结果打印0

用户

+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| UserID  | mediumint(9) | NO | PRI | NULL | auto_increment | 
| firstName | varchar(15) | NO |  | NULL |    | 
| lastName | varchar(15) | NO |  | NULL |    | 
| Protocol | varchar(10) | NO |  | NULL |    | 
| Endpoint | varchar(50) | NO |  | NULL |    | 
| UsergroupID | mediumint(9) | NO | MUL | NULL |    | 
+-------------+--------------+------+-----+---------+----------------+ 

认购

+----------------+--------------+------+-----+---------+----------------+ 
| Field   | Type   | Null | Key | Default | Extra   | 
+----------------+--------------+------+-----+---------+----------------+ 
| SubscriptionID | mediumint(9) | NO | PRI | NULL | auto_increment | 
| TopicID  | mediumint(9) | NO | MUL | NULL |    | 
| UserID   | mediumint(9) | NO | MUL | NULL |    | 
+----------------+--------------+------+-----+---------+----------------+ 

主题

+----------+--------------+------+-----+---------+----------------+ 
| Field | Type   | Null | Key | Default | Extra   | 
+----------+--------------+------+-----+---------+----------------+ 
| TopicID | mediumint(9) | NO | PRI | NULL | auto_increment | 
| Name  | varchar(50) | NO |  | NULL |    | 
| FBName | varchar(30) | YES |  | NULL |    | 
| FBToken | varchar(255) | YES |  | NULL |    | 
| TWName | varchar(10) | YES |  | NULL |    | 
| TWToken | varchar(50) | YES |  | NULL |    | 
| TWSecret | varchar(50) | YES |  | NULL |    | 
+----------+--------------+------+-----+---------+----------------+ 

我的SQL查询来尝试并获得计数:

SELECT Topic.TopicID as ID, Topic.Name AS TopicName, COUNT(*) AS numSubscriptions 
FROM User, Topic, Subscription 
WHERE Subscription.UserID = User.UserID 
    AND Subscription.TopicID = Topic.TopicID 
GROUP BY Topic.TopicID; 

我试过用IFNULL(COUNT(*), 0)代替COUNT(*),我试着用User JOIN Subscription JOIN Topic代替User,Topic,Subscription,我也试过User LEFT JOIN Subscription LEFT JOIN Topic,但是得到了SQL错误。

我得到的输出是:

+----+-----------+------------------+ 
| ID | TopicName | numSubscriptions | 
+----+-----------+------------------+ 
| 2 | test  |    2 | 
| 3 | test2  |    1 | 
+----+-----------+------------------+ 

我需要越来越

+----+-----------+------------------+ 
| ID | TopicName | numSubscriptions | 
+----+-----------+------------------+ 
| 2 | test  |    2 | 
| 3 | test2  |    1 | 
| 4 | test3  |    0 | 
+----+-----------+------------------+ 

回答

1

默认情况下,外部联接从左到右。因此,关键是要开始主题:

SELECT Topic.TopicID as ID, Topic.Name AS TopicName, 
    COUNT(User.UserID) AS numSubscriptions 
FROM Topic 
LEFT JOIN Subscription 
    ON Subscription.TopicID = Topic.TopicID 
JOIN User 
    ON User.UserID = Subscription.UserID 
GROUP BY Topic.TopicID 

这允许每个用户多个订阅,并要求用户记录存在于计数加以考虑。

COUNT(NULL)的计算结果为0,因此任何没有相应订阅和用户记录的主题记录都会显示为0

如果你不关心用户记录是否存在,您可以将其简化为以下几点:

SELECT Topic.TopicID as ID, Topic.Name AS TopicName, 
    COUNT(Subscription.TopicID) AS numSubscriptions 
FROM Topic 
LEFT JOIN Subscription 
    ON Subscription.TopicID = Topic.TopicID 
GROUP BY Topic.TopicID 
+0

底部一个做到了 – avorum

0

下面的例子应该做你以后。 COUNT()中的列可以是订阅表的任何列,但使用其ID是一种很好的做法。

使用左连接可确保用户表的所有条目都将显示在结果中,即使没有匹配的订阅也是如此。

SELECT User.firstName, 
     User.lastName, 
     Topic.Name AS TopicName, 
     COUNT(Subscription.SubscriptionId) AS numSubscriptions 
FROM USER 
LEFT OUTER JOIN Subscription ON Subscription.UserID=USER.UserID 
LEFT OUTER JOIN Topic ON Subscription.TopicID=Topic.TopicID 
GROUP BY User.firstName, User.lastName, Topic.Name; 
+0

这仍然没有得到我行有0项为TEST3话题。另外,我编辑了这个问题,我首先不小心输入了错误的查询,实际上我并不在意这个查询的用户名。 – avorum