我没有任何代码或数据库可供显示,因为我处于计划阶段,我无法找到正确的方法来执行此操作。
我想确定用户是否在一周内每天都执行了特定操作。如果他们有我想要执行一个动作。每次休息几天,我都需要重置。
例如:
Day 1 | task performed 25 times
Day 2 | task performed 13 times
Day 3 | task performed 18 times
Day 4 | task not performed... start over at Day 1.
.....
Day 1 | task performed 3 times
Day 2 | task performed 11 times
Day 3 | task performed 14 times
Day 4 | task performed 7 times
Day 5 | task performed 3 times
Day 6 | task performed 10 times
Day 7 | task performed 23 times
echo'您已经连续7天成功完成了71项任务';
我想真正的问题是,实现这一目标的最佳方法是什么?我是否应该尝试根据日期存储7个cookie,如果最新的cookie值超过24小时,则销毁所有现有的cookie?我应该尝试通过数据库设置和更新日期吗?
建议作为实现这一点的潜在解决方案是我正在寻找的,请记住这是我正在研究的数据库密集型应用程序,因此数据库调用IMO越少越好。
更新
所以我试图用数据库来计划这个,我只是在各个角度遇到问题。
如果我尝试设置增量列,则无法确定上次更新的时间。
如果我设置了一个表,那么它非常复杂,因为我必须将值基于连续日期。所以我不能做一个简单的7天搜索,我必须测试每个结果是否在数据库中先前结果集的24小时内,否则我将如何区分在第1,3天完成任务的人,和7对比那个做1,2,3,4,5,6和7的人。
清理数据库同样麻烦。我该如何进行清理。我不能简单地测试数据是否在当前日期的7天内,因为这并不能说明某人在第5天完成任务而不是第6天...然后在第7天......同样也很复杂因为每个用户都有不同的开始日期。所以我可能已经开始今天的任务和5天前的另一个用户。我可以放心地假设7天以上的所有日期都已过期,但这并不能确定几天内的休息时间。
我很困惑如何真正完成这项任务。
答案 0 :(得分:1)
将您的数据保存在数据库中,因为cookie的问题是用户可以随时清理他/她的浏览器。数据库中的数据可以随时处理。
假设您将此格式的数据保存在数据库中:
File file = new File("/home/user/Desktop/linux/myString.txt");
StringBuilder fileContents = new StringBuilder((int) file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");
try {
while (scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + lineSeparator);
}
line2 = fileContents.toString().trim();
} finally {
scanner.close();
}
int location = 0, i = 0;
String[] newLine2 = line2.split("mySearch"); // Spliting my code to smallers parts
System.out.println("Times found: " + (newLine2.length - 1) + ".");// Gives the correct answer, it does find the search term
boolean foundMyWord = false;
for (i = 0; i <= newLine2.length - 2; i++) {
int topA = 0, a = 0;
String text = newLine2[i].replaceAll("[\r\n]+", " ").toString().toLowerCase().trim();
int size = text.length();
System.out.println("text size= " + size);// Returns 0
topA = text.indexOf("notYourLine");//If the segment has this word inside,my word isnt located in it
a = text.indexOf("neitherInThisSegment");//If the segment has this word inside,my word isnt located in it
if ((topA <= 0) || (a <= 0)) {
foundMyWord = true;
}
i++;
System.out.println("Lines= " + i);
if (foundMyWord == true) {
location = i;
System.out.println("The word was inside segment = " + location);
break;
}
}
您只需运行查询即可删除数据:
Description | task_id | created
Task perfor. | 2 | 2016-10-17
Task perfor. | 2 | 2016-10-17
Task perfor. | 2 | 2016-10-18
Task perfor. | 2 | 2016-10-18
一个查询可以清理您的数据,这根本不是很混乱。即使是庞大的数据库也是这样处理的。
答案 1 :(得分:1)
有几种方法可以做到这一点。
如果您使用数据库路径,可以使用此SQL fiddle
的引用我不知道数据库密集程度如何,但我认为如果你走这条路,我会总结一下所需的工作。这条路线的优点是你不必删除或重置任何东西,所以你将拥有历史数据,例如你可以得到多少&#34;尝试&#34;用户通过将上述查询更改为having count(distinct d) < 7
(它会返回尽可能多的用户尝试完成任务的行)
另一种方法是,您可以使用基于文件的数据,例如在服务器端为执行任务的每个用户使用JSON文件。使用此路由,您需要自己维护数据,例如,您有这个简单的JSON结构:
{
"day1": "2016-09-01",
"last_task": "2016-09-03",
"accumulated_task": "56"
}
我自己维护数据的意思是,每次应用更改时都需要更新,例如当前日期为2016-09-05
且last_task
为2016-09-03
,那么您需要重置它。这条路线的优点当然不是数据库开销,而是许多人工劳动&#34;。
答案 2 :(得分:1)
这将假设我们的测试页面ID = 9 ...被查看,计算徽章(用户看到该页面连续7天)。这个事实被拉出了评论(7天和徽章)。至于第9页,我们刚刚在这个答案中提到了这一点。
因此,如果用户连续7天查看该页面,我们希望输出中的用户。注意,页码是9。
create schema db40076704;
use db40076704;
create table pageViews
( id int auto_increment primary key,
userId int not null,
viewDT datetime not null,
pageId int not null
-- include decent index choices here
-- include Foreign Key constraints here
);
truncate pageViews;
insert pageViews (userId,viewDT,pageId) values
(101,'2016-09-05 21:00:00',9),
(101,'2016-09-06 11:00:00',9),
(101,'2016-09-06 15:55:00',9),
(101,'2016-09-06 15:57:00',9),
(101,'2016-09-07 21:00:00',9),
(101,'2016-09-08 21:00:00',999999),
(101,'2016-09-09 21:00:00',9),
(101,'2016-09-10 21:00:00',9),
(101,'2016-09-11 21:00:00',9),
(150,'2016-09-01 21:00:00',9),
(150,'2016-09-06 11:00:00',9),
(150,'2016-09-06 15:55:00',9),
(150,'2016-09-06 15:57:00',9),
(150,'2016-09-07 21:00:00',9),
(150,'2016-09-08 10:44:00',9),
(150,'2016-09-09 21:00:00',9),
(150,'2016-09-10 21:00:00',9),
(150,'2016-09-11 23:00:00',9),
(150,'2016-09-12 23:00:00',9),
(200,'2016-09-08 10:44:00',9),
(200,'2016-09-10 21:00:00',9),
(200,'2016-09-12 21:00:00',9),
(200,'2016-09-14 23:00:00',9),
(200,'2016-09-16 23:00:00',9),
(200,'2016-09-18 23:00:00',9),
(200,'2016-09-20 23:00:00',9);
select userId,
date(viewDT),
(@rn := if(@curUser = userId
AND (@prevDate=DATE(viewDT) OR @prevDate=DATE_SUB(DATE(viewDT),INTERVAL 1 DAY)), @rn,
if(@curUser := GREATEST(userId,-1), @rn+1, @rn+1)
)
) rn,
@prevDate:=DATE(viewDT) as dummy1
from pageViews
join (select @curUser:=-1,@prevDate:='',@rn:=0) params
where pageId=9
order by userId,viewDt;
+--------+--------------+------+------------+
| userId | date(viewDT) | rn | dummy1 |
+--------+--------------+------+------------+
| 101 | 2016-09-05 | 1 | 2016-09-05 |
| 101 | 2016-09-06 | 1 | 2016-09-06 |
| 101 | 2016-09-06 | 1 | 2016-09-06 |
| 101 | 2016-09-06 | 1 | 2016-09-06 |
| 101 | 2016-09-07 | 1 | 2016-09-07 |
| 101 | 2016-09-09 | 2 | 2016-09-09 |
| 101 | 2016-09-10 | 2 | 2016-09-10 |
| 101 | 2016-09-11 | 2 | 2016-09-11 |
| 150 | 2016-09-01 | 3 | 2016-09-01 |
| 150 | 2016-09-06 | 4 | 2016-09-06 |
| 150 | 2016-09-06 | 4 | 2016-09-06 |
| 150 | 2016-09-06 | 4 | 2016-09-06 |
| 150 | 2016-09-07 | 4 | 2016-09-07 |
| 150 | 2016-09-08 | 4 | 2016-09-08 |
| 150 | 2016-09-09 | 4 | 2016-09-09 |
| 150 | 2016-09-10 | 4 | 2016-09-10 |
| 150 | 2016-09-11 | 4 | 2016-09-11 |
| 150 | 2016-09-12 | 4 | 2016-09-12 |
| 200 | 2016-09-08 | 5 | 2016-09-08 |
| 200 | 2016-09-10 | 6 | 2016-09-10 |
| 200 | 2016-09-12 | 7 | 2016-09-12 |
| 200 | 2016-09-14 | 8 | 2016-09-14 |
| 200 | 2016-09-16 | 9 | 2016-09-16 |
| 200 | 2016-09-18 | 10 | 2016-09-18 |
| 200 | 2016-09-20 | 11 | 2016-09-20 |
+--------+--------------+------+------------+
25 rows in set (0.00 sec)
SELECT userId,rn,count(*) days_In_A_Row
from
( SELECT userId,
DATE(viewDT),
(@rn := if(@curUser = userId
AND (@prevDate=DATE(viewDT) OR @prevDate=DATE_SUB(DATE(viewDT),INTERVAL 1 DAY)), @rn,
if(@curUser := GREATEST(userId,-1), @rn+1, @rn+1)
)
) rn,
@prevDate:=DATE(viewDT) as dummy1
FROM pageViews
JOIN (SELECT @curUser:=-1,@prevDate:='',@rn:=0) params
WHERE pageId=9
ORDER BY userId,viewDt
) xDerived
GROUP BY userId,rn
HAVING days_In_A_Row>6;
+--------+------+---------------+
| userId | rn | days_In_A_Row |
+--------+------+---------------+
| 150 | 4 | 9 |
+--------+------+---------------+
因此,用户150连续至少7天(实际上连续9天)查看了第9页。该用户在您的系统中获得徽章。
关于mysql变量的一些信息(@变量)。为了安全地使用变量,必须注意不要假设select的任何输出列将在另一个之前触发。这是在题为User-Defined Variables:
的手册页中明确说明的事实在下面的语句中,您可能会认为MySQL会进行评估 首先是@a,然后是第二个任务:
SELECT @a, @a:=@a+1, ...;
但是,评估顺序为 涉及用户变量的表达式是未定义的。
也就是说,我们知道使用GREATEST(),LEAST()和COALESCE()等函数会被强制优先。
GREATEST(N,-1)代码中的废话总是会返回N.但我们需要强制在
之前计算该列的优先级。@prevDate:=DATE(viewDT) as dummy1
线。另请参阅Baron Schwartz的强制阅读 Advanced MySQL user variable techniques。