2011-03-07 63 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