左联接减少返回的行数

时间:2019-01-23 15:40:50

标签: mysql

我想计算一次事件发生前一小时内某行为发生的次数。这需要联接两个表。第一个表具有事件的时间和一个小时之前的时间,第二个表具有行为的每个实例的时间戳。

我目前正在尝试使用左联接联接表,但是由于使用WHERE命令指定仅对小时内的行为进行计数,因此我认为这正在减少返回的行数。我希望对事件发生前一小时的行为次数进行计数,即使该次数为零也是如此。

我的代码如下所示:

SELECT Table1.*, 
COUNT(Table2.`BehaviourTime`) AS CountBefore

FROM Table1

LEFT JOIN Table2 on Table1.`Date` = Table2.`Date` AND Table1.`GroupRef` = 
Table2.`GroupRef`

WHERE Table2.`BehaviourTime` BETWEEN Table1.`HourBefore` AND 
Table1.`EventTime`

GROUP BY `Date`, `GroupRef`, `Session`

我期望Table1的每一行都有一个计数(因为每一行代表一个事件),但是每次返回的行都更少。我需要针对不同的行为对此做类似的变化。

我的代码是否有问题,或者是一种更简单的方式来获取所需的输出而又不会丢失数据?

感谢您的帮助!


更新

预期结果(返回1917行):

Session    Date    GroupRef HourBefore  EventTime   CountBefore
A          1/1/19  XX       09:32:46    10:32:46    3  
P          1/1/19  XX       15:55:02    16:55:02    0
A          4/1/19  XX       06:49:12    07:49:12    8
....

实际结果返回1306行,没有零计数。

Session    Date    GroupRef HourBefore  EventTime   CountBefore
A          1/1/19  XX       09:32:46    10:32:46    3  
A          4/1/19  XX       06:49:12    07:49:12    8
.....

1 个答案:

答案 0 :(得分:0)

您应将左连接表的条件添加到on子句

SELECT Table1.*, 
COUNT(Table2.`BehaviourTime`) AS CountBefore
FROM Table1
LEFT JOIN Table2 on Table1.`Date` = Table2.`Date` AND Table1.`GroupRef` = 
Table2.`GroupRef`  
     AND Table2.`BehaviourTime` BETWEEN Table1.`HourBefore` AND  Table1.`EventTime`
GROUP BY `Date`, `GroupRef`, `Session`

否则,如果您在where子句中保留与左联接表的列相关的条件,则它们将作为INNER JOIN起作用

对于CountBefore的= 0值,您可能需要ifnull检查

SELECT Table1.*, ifnull(COUNT(Table2.`BehaviourTime`),0) AS CountBefore
FROM Table1

LEFT JOIN Table2 on Table1.`Date` = Table2.`Date` 
    AND Table1.`GroupRef` = Table2.`GroupRef`
      AND Table2.`BehaviourTime` 
          BETWEEN Table1.`HourBefore` AND Table1.`EventTime`
GROUP BY `Date`, `GroupRef`, `Session`

或者尝试使用sum来检查是否为空

SELECT Table1.*
    , sum(case when table2.`BehaviourTime` is null then 0 else 1 end ) AS CountBefore
FROM Table1

LEFT JOIN Table2 on Table1.`Date` = Table2.`Date` 
    AND Table1.`GroupRef` = Table2.`GroupRef`
      AND Table2.`BehaviourTime` 
          BETWEEN Table1.`HourBefore` AND Table1.`EventTime`
GROUP BY `Date`, `GroupRef`, `Session`