2014-07-08 63 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