基于日期范围的两个表的左联接

时间:2019-06-05 16:42:54

标签: sql left-join

我是SQL编码的新手,并且正在尝试弄清楚如何基于日期范围创建LEFT JOIN语句。该数据库是来自智能手机应用程序的分析,该应用程序将消息发送给用户。这两个表是messageLog(描述发送给每个用户的消息)和messageOpenLog(描述打开的消息)。这两个表都链接到消息表,但彼此不链接。使事情变得复杂的是,我们还制定了一些其他规则,以便能够发送消息:

  1. 如果7天内未打开邮件,则可以在第8天重新发送该邮件。
  2. 如果打开了一条消息,则可以在60天内重新发送该消息。

所以,我要做的是基于以下伪代码将两个表连接在一起(因为我不知道从哪里开始使用实际代码):

LEFT JOIN 
If (messageOpenLog.DateOpened is within 7 days of messageLog.DateSent) 
and messageLog.message_id = messageOpenLog.message_id and 
messageLog.user_id = messageOpenLog.user_id

注意:两个表中的日期格式均为yyyy-mm-dd hh:mm:ss。

我们将不胜感激。

3 个答案:

答案 0 :(得分:1)

我无法评论shn的答案,但是用户可能从未打开过该消息,并且尚未创建messageOpenLog记录。在这种情况下,您可以在where子句中添加messageOpenLog.message_id is null并获取那些没有相应的messageOpenLog记录的未打开消息。

答案 1 :(得分:0)

根据我对您的问题和下面的查询的了解,您发现所有单独的邮件在其发送日期和打开日期之间的时间差超过7天。

要实现时差,我建议使用SQL内置的DATEDIFF()函数(您可能需要使用DATE()将时间戳记格式化为日期格式)。

由于这两个表没有直接关联,因此您可以执行以下操作:

SELECT 
   messageOpenLog.*, 
   messageLog.* 
FROM 
   messageLog LEFT JOIN messageOpenLog ON messageLog.message_id=messageOpenLog.message_id 
WHERE
   messageLog.user_id = messageOpenLog.user_id AND
   DATEDIFF(
      day, 
      DATE(messageLog.timestamp), 
      DATE(messageOpenLog.timestamp)
   ) > 7

此查询的结构取决于表的构造。 注意,我使用了.timestamp列,但是在您的表中,这可能被命名为别的。
我也不确定这是否真的是您想要的;如果要查看邮件是否已存在7天以上,则需要其他查询。

假设只有一条messageSent行,此查询将获取7天以上的同一条消息的所有messageOpen行。

很难根据显示的信息为您提供准确的查询,例如具有相同message_id的潜在行数,如@amac所提到的,在某些情况下,其中一个表可能没有行带有特定的message_id。

答案 2 :(得分:0)

我建议:

messagelog  ml LEFT JOIN
messageOpenLog mol
ON mol.message_id = ml.message_id AND
   mol.user_id = ml.user_id AND
   mol.DateOpened >= ml.DateSent AND  -- probably not needed
   mol.DateOpened < ml.DateSent + interval '7 day'

请注意,数据库之间的日期算术差异很大。添加7天的确切语法在您的数据库中可能会有所不同。