2011-03-07 84 views
3

這兩個查詢有可能不同。我的意思是第一個查詢沒有包括我左表中的所有行,所以我把條件放在了連接部分中。兩個SQL聯接,兩個不同的結果

查詢1

SELECT COUNT(*) as opens, hours.hour as point 
FROM hours 
LEFT OUTER JOIN tracking ON hours.hour = HOUR(FROM_UNIXTIME(tracking.open_date)) 
WHERE tracking.campaign_id = 83 
AND tracking.open_date < 1299538799 
AND tracking.open_date > 1299452401 
GROUP BY hours.hour 

查詢2

SELECT COUNT(*) as opens, hours.hour as point 
FROM hours 
LEFT JOIN tracking ON hours.hour = HOUR(FROM_UNIXTIME(tracking.open_date)) 
AND tracking.campaign_id = 83 
AND tracking.open_date < 1299538799 
AND tracking.open_date > 1299452401 
GROUP BY hours.hour 

不同的是,第一個查詢給我18行,其中有17點之間沒有行至22但是當我運行第二個查詢,它顯示完整的24行,但對於17到22之間的行,它的值爲!我希望它是0或NULL?如果它真的是1,它應該沒有出現在第一個查詢中?

這是怎麼發生的?

回答

3

您使用的是COUNT(*),它會計算結果集中的每一行(因爲它被寫入),因爲即使沒有tracking中的數據,您的數據也是hours

嘗試更改COUNT(*)COUNT(tracking.open_date)(或tracking內的任何不可空列;它們之間沒有關係)。

+0

啊!我錯過了。非常感謝你! – Abs 2011-03-07 19:17:10

+0

糟糕,我的錯誤,你是對的。你更快。 – Abs 2011-03-07 19:26:58

+0

@erikkallen:你會這樣想,但是在所有的RDBMS引擎中情況並非如此。據我所知,MySQL中的MyISAM和InnoDB引擎(以及MS SQL Server引擎)不計算'null'的實例。我不能爲別人說話,但它似乎解決了OP的問題。 – 2011-03-07 19:29:50

1

COUNT(*)統計查詢中產生的行數。

您可以使用count(tracking.open_date),從跟蹤表(右表)

+0

3正確的答案 - 它將不得不下降到時間。你是最快的。 – Abs 2011-03-07 19:18:48

+1

-1; 'left join'和'left outer join'是同義詞。所有'left'和'right'連接都是'outer'自動連接。內連接(您首先描述的)不能被指定爲「左」或「右」,因爲只有在兩側匹配時才包含行。 – 2011-03-07 19:20:07

+1

@Abs:你可以在「5分鐘前」懸停(或者它所說的任何答案)以查看發佈時間。爲了記錄,這個答案在我的兩分鐘後發佈。 – 2011-03-07 19:21:02

5

第一JOIN基本上任何列實際上是一個INNER JOIN,外連接表不應該出現在WHERE子句中就像你在上面查詢有,而不是COUNT(*),從外連接表中選取一列

0

問題是第一個查詢將執行外連接,其中一些行在跟蹤表的所有表中都包含NULL。然後它將在這些跟蹤列上應用過濾器,並且由於它們爲空,結果集中的相應行將被過濾掉。

第二個查詢將在所有列上執行正確的外連接。

+0

這正確地解決了爲什麼第一個查詢的行爲像內部聯接(因爲,正如你指出的那樣,它基本上*是*),但它沒有解決他的問題,當他在'COUNT'中沒有值時爲'COUNT' tracking'。 – 2011-03-07 19:32:00