我正在调查两个DB表中两个不同条目的因果关系,这些表没有可链接的公共ID。

我唯一拥有的是一个中的unix时间戳,另一个中的date time列。我很确定某个操作会触发另一个操作,但是我需要仔细检查。

所以我尝试了这样的事情:

SELECT * FROM requestsRIGHT JOIN log_service on (log_service.date is BETWEEN FROM_UNIXTIME(1512312363) and FROM_UNIXTIME(1512312363+2))

例如,我在请求表中具有timestamp_send为1512312363的行,并且我在log_service表中具有两个匹配的行,其日期值类似于:2017-12-03 16:46:02
2017-12-03 16:46:03
(其GMT + 2)

因此,我想正确地加入log_service表,并将其与我正在查看的请求相关联。

上面的查询尝试不起作用。
它返回:
ELECT * FROM requestsRIGHT JOIN log_service on (log_service.date is BETWEEN FROM_UNIXTIME(1512312363) and FROM_UNIXTIME(1512312363+2))1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BETWEEN FROM_UNIXTIME(1512312363) and FROM_UNIXTIME(1512312363+2))' at line 2Time: 0.189s

显然,完成的查询中的硬编码数字将是左表中的requests.timestamp_send列。

有什么建议怎么做?

最佳答案

正如我在对该问题的评论中指出的那样,首先,请在IS之前删除伪造的BETWEEN关键字。 (IS关键字用于比较布尔表达式,它不是BETWEEN比较运算符的一部分。)

对于日期时间范围比较,我们通常使用两次比较的模式,只有一侧包含相等性。

       foo >= start  AND  foo < end


关于此的原因以及BETWEEN引入的意外错误,有一些不错的文章。但这可能不适合您的特殊用例,在这种情况下,您确实确实希望比较的两面都相等。我仍然建议使用两次比较的模式,即使这意味着我们必须重复一个表达式。

       foo >= start  AND  foo <= end


我还建议放弃SELECT列表中的*,并特别列出查询应返回的表达式。这为将来的读者提供了列名,列数以及更多指示,这些列实际上是您感兴趣的。

另外,似乎我们想查找与“我正在查看的请求”关联的log_service行。这表明可能存在一些准则来标识我们感兴趣的request行。

它还建议我们要从请求返回行,并从log_service返回所有匹配的行...这表明外部联接将是相反的方式,即LEFT联接而不是RIGHT联接。

下一个问题是确定“日期”和“ unix时间戳”比较中涉及的列的实际数据类型。没有这些信息,我们只是在猜测... timestamp_send中的request列是INTEGER类型,并且包含自纪元开始以来的unix样式秒数,以及date中的log_service列是DATETIME。

根据提供的规范,我们倾向于编写如下查询:

SELECT rq.timestamp_send                AS rq_timestamp_send
     , FROM_UNIXTIME(rq.timestamp_send) AS rq_datetime_send
     , ls.date
     , ls.foo
     , ...
  FROM requests rq
  LEFT
  JOIN log_service ls
    ON ls.date >= FROM_UNIXTIME( rq.timestamp_send )
   AND ls.date  < FROM_UNIXTIME( rq.timestamp_send ) + INTERVAL 3 SECOND
 WHERE rq.somecol = 'the request i am looking at'

关于mysql - 如何仅基于连接线之间?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47666704/

10-12 13:04