我有一个MySql-8.0 / MariaDb-10.4表,其中包含不同访客的站点访问列表:
我想创建一个查询,该查询返回每次访问会话的首次访问,其中会话定义是CreatedAt
日期为30分钟或更多来自以前的访问。
因此,在我的情况下,我应该返回第2行(Id列),第8行和第13行。请注意,一次会话可以超过30分钟,只要每次访问在不到30分钟的时间内成功完成上一次访问
我的解决方法如下:
SELECT DISTINCT a.`CreatedAt`
FROM activities AS a
LEFT JOIN activities AS b
ON (
(UNIX_TIMESTAMP(b.`CreatedAt`) >= (UNIX_TIMESTAMP(a.`CreatedAt`) - (30 * 60)) ) AND
(b.`CreatedAt` < a.`CreatedAt`)
)
WHERE (b.`CreatedAt` IS NULL) AND (a.`VisitorId` = '26924c19-3cd1-411e-a771-5ebd6806fb27' /* or others for example */ )
它可以正常工作,但是它不返回最后一行13,同样我不确定这不是最好的解决方案。预先感谢。
答案 0 :(得分:2)
解决此问题的最简单方法是将所有访问与他们的较早兄弟姐妹联系起来,然后仅选择那些没有访问的兄弟姐妹。如果没有以后的访问(例如您的ID为13的示例),则(更直观)握拳的另一种方法会失败,但以后。
SELECT
late.*
FROM activities AS late
LEFT JOIN activities AS early
ON late.VisitorId=early.VisitorId
AND late.CreatedAt>early.CreatedAt
AND late.CreatedAt<=DATE_ADD(early.CreatedAt, INTERVAL +30 MINUTE)
WHERE early.Id IS NULL
-- Maybe: AND late.VisitorId='26924c19-3cd1-411e-a771-5ebd6806fb27'
-- Maybe: ORDER BY late.CreatedAt
答案 1 :(得分:1)
我对@Eugen Rieck https://stackoverflow.com/a/61027502/625144也有类似的答案。但是使用MySQL
TIMESTAMPDIFF
函数
SELECT a.*,
FROM activities a
LEFT JOIN activities b
ON b.VisitorId = a.VisitorId
AND a.Id > b.Id
AND TIMESTAMPDIFF(MINUTE, b.CreatedAt, a.CreatedAt) <= 30
WHERE
b.Id IS NULL
;