使用WHERE子句时,SQL JOIN不显示NULL结果

时间:2015-05-04 15:02:18

标签: sql-server sql-server-2008

服务器: SQL Server 2008 R2
SQL小提琴: http://sqlfiddle.com/#!6/112a6/4/0

我为可怜的主题/标题道歉,但我很难说出如何陈述我的问题,所以我会用一个(可能)冗长的例子来画出来:

下面是一个相当简单的查询,它可以获取特定日期范围内PC的会话数。请注意,WHERE子句已被注释掉。我希望收到的是完整的PC列表,即使是在该范围内具有ZERO / NULL会话的PC。但是,当我添加WHERE子句时,我只能获得在该范围内有会话的PC。这是有问题的,因为我无法看到在此期间未使用的PC。

SELECT 
    f_assetnetbiosname, 
    COUNT(f_sessiondate) as 'Sessions'
FROM 
    tb_assets ass
LEFT JOIN 
    tb_sessions ses
  ON 
    ses.f_sessionnetbiosname = ass.f_assetnetbiosname  
--WHERE (f_sessiondate BETWEEN '04/01/2015' AND '04/30/2015')
GROUP BY f_assetnetbiosname

========================   =======================================|
| tb_assets            |   | tb_sessions                          |
========================   =======================================|
|   f_assetnetbiosname |   |  f_sessionnetbiosname  f_sessiondate |
------------------------   ---------------------------------------|
|     COMP_001         |   |    COMP_002            03/29/2015    |
|     COMP_002         |   |    COMP_002            03/30/2015    |
|     COMP_003         |   |    COMP_001            03/30/2015    |
------------------------   |    COMP_001            04/02/2015    |
                           |    COMP_001            04/03/2015    |
                           |    COMP_001            04/04/2015    |
                           |    COMP_001            04/05/2015    |
                           -----------------------------------

基于这些结果的查询返回以下结果集:

|=================================|
| f_assetnetbiosname  | Sessions  |
|=================================|
| COMP_001            | 5         |
| COMP_002            | 2         |
| COMP_003            | 0         |
|=================================|

问题是我需要实际搜索日期范围。所以,如果我取消注释" WHERE"在上面的查询中,结果集看起来只有以下内容:

|=================================|
| f_assetnetbiosname  | Sessions  |
|=================================|
| COMP_001            | 4         |
|=================================|

但我需要它看起来如下所示,以便我可以看到没有会话的PC:

|=================================|
| f_assetnetbiosname  | Sessions  |
|=================================|
| COMP_001            | 4         |
| COMP_002            | 0         |
| COMP_003            | 0         |
|=================================|

有人有解决方法吗?请注意,上面的例子只是一个例子。真正的查询是一个多CTE熊猫,但我认为最好将其简化为基础,这样我就不会通过炫耀我的不良代码来实现对话。

SQL小提琴http://sqlfiddle.com/#!6/112a6/4/0

提前致谢,
Beems

2 个答案:

答案 0 :(得分:5)

您可以将其添加到Join子句:

SELECT 
    f_assetnetbiosname, 
    COUNT(f_sessiondate) as 'Sessions'
FROM 
    tb_assets ass
LEFT OUTER JOIN 
    tb_sessions ses
  ON 
    ses.f_sessionnetbiosname = ass.f_assetnetbiosname 
    AND f_sessiondate BETWEEN '04/01/2015' AND '04/30/2015'
GROUP BY f_assetnetbiosname

这是一个演示:http://sqlfiddle.com/#!6/112a6/23/0

Join - 条款与Where之间的差异,也提及here

答案 1 :(得分:0)

听起来你只需要根据日期计算,这样你就可以把条件计算在你的数量中。

SELECT f_assetnetbiosname, 
COUNT(CASE WHEN (f_sessiondate BETWEEN '04/01/2015' AND '04/30/2015') 
           THEN 1 ELSE null
           END) as 'Sessions'
FROM tb_assets ass
LEFT JOIN tb_sessions ses ON ses.f_sessionnetbiosname = ass.f_assetnetbiosname  
GROUP BY f_assetnetbiosname

http://sqlfiddle.com/#!6/112a6/27