我正在调查两个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/