我无法设置查询来计算/排列上一次' n '天内事件发生的连续天数。即:如果事件在最后' n '天内连续发生' k '次,则与参考日期无间隙。
从当前日期到过去' n '天的视觉(0表示无事件,1表示事件):
case A - 01111 (count as 0 since there's no event in the previous date).
case B - 11001 (count as 2 consecutive days)
case C - 11110 (count as 4 consecutive days)
case D - 00110 (also count as 0)
case E - 10111 (count as 1)... and so on
考虑'伪'结构:
Table1
uid
eventid
table2
eventid
datetime
我需要的结果是uid的'等级'在最近n天内有连续事件,所以如果我在表1和表2中得到这些值:
Table1
(1, 100)
(1, 101)
(1, 102)
(1, 103)
(2, 104)
(2, 105)
(2, 106)
Table2
(100, '2015-09-11 00:00:00')
(101, '2015-09-10 00:00:00')
(102, '2015-09-09 00:00:00')
(103, '2015-09-07 00:00:00')
(104, '2015-09-11 00:00:00')
(105, '2015-09-10 00:00:00')
(106, '2015-09-05 00:00:00')
结果应该是:
uid - consecutive
1 - 3
2 - 2
这意味着uid 1在最后几天连续发生了事件100,101和102但是偶数103因为不连续而被淘汰。
我正在寻找similar questions并尝试应用其中一些,但没有人根据参考(当前)日期考虑连续几天。
接近我来的是使用每个案例的日期进行左连接,类似于:
SELECT * FROM
(SELECT * FROM Table1 LEFT JOIN Table2 USING (uid) WHERE date(datetime)=curdate()-interval 3 day)
LEFT JOIN (SELECT * FROM Table1 LEFT JOIN Table2 USING (uid) WHERE date(datetime)=curdate()-interval 2 day)
LEFT JOIN (SELECT * FROM Table1 LEFT JOIN Table2 USING (uid) WHERE date(datetime)=curdate()-interval 1 day)
此外,我在SQL中使用var的知识几乎都没有,如果可能的话,我想避免使用过程,从php内部调用mysql。
THX
答案 0 :(得分:1)
您可以使用计数器变量来做到这一点。
首先,我们会获得一个包含uid
和datetime
列的表格,并且排序正确:
SELECT `uid`,`datetime` FROM `table1`
INNER JOIN `table2` ON `table1`.`eventid`=`table2`.`eventid`
ORDER BY `uid`, `datetime`
现在我们将其用作子查询,每当uid
与最后一行相同时推进计数器,datetime
比最后一行的日期提前1天。以下是它的完成方式:
SET @counter = 1;
SET @lastDate = '2010-01-01 00:00:00';
set @lastUid = 0;
SELECT
`uid`,
IF (((DATE_ADD(@lastDate, INTERVAL 1 DAY)=`datetime`) AND (`uid`=@lastUid)),
@counter := @counter+1, @counter := 1),
(@lastUid := `uid`),
(@lastDate := `datetime`),
@counter as `counter`
FROM (
SELECT `uid`,`datetime` FROM `table1`
INNER JOIN `table2` ON `table1`.`eventid`=`table2`.`eventid`
ORDER BY `uid`, `datetime` ASC
) `uidDateTable`
现在我们要做的就是将该查询用作子查询,并找到每MAX
counter
uid
的{{1}}值。这就是你需要的实际查询:
SET @counter = 1;
SET @lastDate = '2010-01-01 00:00:00';
set @lastUid = 0;
SELECT `uid`, max(`counter`)
FROM (
SELECT
`uid`,
IF (((DATE_ADD(@lastDate, INTERVAL 1 DAY)=`datetime`) AND (`uid`=@lastUid)),
@counter := @counter+1, @counter := 1),
(@lastUid := `uid`),
(@lastDate := `datetime`),
@counter as `counter`
FROM (
SELECT `uid`,`datetime` FROM `table1`
INNER JOIN `table2` ON `table1`.`eventid`=`table2`.`eventid`
ORDER BY `uid`, `datetime` ASC
) `uidDateTable`
) `uidCounters`
GROUP BY `uid`;