我正在用PHP执行MySQL脚本。 所以我有3张桌子。
包含至少3 000 000行的邮件 (userid,messageid,timestamp,received,opened,clicked,deliveryid)
用户 (用户(唯一),个人资料,profile_actual_timestamp,last_delivery_id_sent)
events_clicked_data包含至少2 000 000行和详细点击事件。此用户在此消息(deliveryId)上单击此配置文件(如GAMES) (userid,profile,deliveryId,eventDate)
所以这里是消息和用户表的示例数据。
CREATE TABLE messages
(`user_id` varchar(100), `message_id` int, `timestamp` datetime, `received` varchar(5), `opened` varchar(5), `clicked` varchar(5), `delivery_id` int);
INSERT INTO messages
(`user_id`, `message_id`, `timestamp`, `received`, `opened`, `clicked`, `delivery_id`)
VALUES
("BillyStuff", 12,'2016-05-16 00:00:00', 'true', 'true', 'true', 8),
("BillyStuff", 11,'2016-05-14 00:00:00', 'true', 'true', 'true' , 7),
("BillyStuff", 8,'2016-04-03 00:00:00', 'true', 'false', 'false' , 6),
("BillyStuff", 4,'2016-04-02 00:00:00', 'true', 'false', 'false', 5),
("JohnDoe", 15 ,'2016-05-16 00:00:00', 'true', 'true', 'false' , 4),
("JohnDoe", 13 ,'2016-05-14 00:00:00', 'true', 'true', 'true', 3),
("Donnie", 15 ,'2016-05-16 00:00:00', 'true', 'true', 'true' , 4),
("Donnie", 13 ,'2016-05-14 00:00:00', 'true', 'true', 'true', 3)
CREATE TABLE users
(`user_id` varchar(100), `profile` varchar(100), `profile_actual_timestamp` datetime, `last_delivery_id_sent` int);
INSERT INTO users
(`user_id`, `profile`, `profile_actual_timestamp`, `last_delivery_id_sent`)
VALUES
("BillyStuff", "Game", "2016-01-01 00:00:00", 1),
("JohnDoe", "Book", "2016-01-01 00:00:00", 1),
("Donnie", "Book", "2016-05-16 00:00:00", 4)
我想让用户在个人资料中点击时间戳(profile_actual_timestamp表示上次更新后)后点击2条消息。
在这种情况下,我只获得BillyStuff,因为如果我检查profile_actual_timestamp,Donnie已经是最新的。
在此之后,如果点击了相同的类别,我需要在events_clicked表中按deliveryId和用户进行检查。
CREATE TABLE events_clicked_data
(`user_id` varchar(100), `profile` varchar(100), `deliveryId` int, `eventDate` datetime);
INSERT INTO users
(`user_id`, `profile`, `deliveryId`, `eventDate`) VALUES
("BillyStuff", "Book", 8,"2016-01-01 00:00:00"),
("BillyStuff", "Book", 7,"2016-01-01 00:00:00"),
("JohnDoe", "Book", 3,"2016-01-01 00:00:00"),
("Donnie", "Book", 4,"2016-05-16 00:00:00"),
("Donnie", "Game", 3,"2016-05-16 00:00:00")
在这种情况下,我需要更新BillyStuff的个人资料并将其更改为" Book"而不是"游戏"因为他在最后一次更新后的最后一条消息中点击了两次相同的类别(profile_actual_timestamp)
所以本周对我来说这是一个非常好的谜题,我想知道你们是否可以帮助我解决这个问题。
originalid = userid(不必要原件,取决于表格)
e.name = profil的名字点击了游戏。
select originalid,
name
from (
select @g := if(@u = originalid, if (@p = name, @g, @g + 1), 1) as grp,
@u := originalid as originalid,
@p := name as name
from (
select u.originalid,
m.message_sendtime_timestamp,
e.name
from bienvenue_nouveau_client_dev u
inner join messages_nouveaux_clients m
on m.originalid = u.originalid
inner join events_clicked_data e
on e.originalId = u.originalid
and e.deliveryId = m.deliveryId
where m.message_sendtime_timestamp >= u.profil_actuel_timestamp
and m.clicked = 'TRUE'
limit 1000000000000000
order by u.originalid,
m.message_sendtime_timestamp desc
) alias
) alias2
where grp = 1
group by originalid, name
having count(*) > 1
无论我改变什么,我都会遇到这样的错误:
答案 0 :(得分:1)
第一个查询可以按如下方式完成:
select u.*
from users u
inner join messages m
on m.user_id = u.user_id
where m.timestamp >= u.profile_actual_timestamp
and m.clicked = 'true'
group by u.user_id
having count(m.message_id) > 1
如果这些事件发生的时间晚于上次更新,则第二个查询将为您提供在最后两次点击事件中使用相同配置文件的用户:
select user_id,
profile
from (
select @g := 0 + if(@u = user_id, if (@p = profile, @g, @g + 1), 1) as grp,
@u := user_id as user_id,
@p := profile as profile
from (
select u.user_id,
m.timestamp,
e.profile
from users u
inner join messages m
on m.user_id = u.user_id
left join events_clicked_data e
on e.user_id = u.user_id
and e.deliveryId = m.delivery_id
where m.timestamp >= u.profile_actual_timestamp
order by u.user_id,
m.timestamp desc
) alias
) alias2
where grp = 1
group by user_id, profile
having count(*) > 1
此查询依赖于变量,并且有点冒险,因为它必须以指定的顺序返回最里面的结果,并且必须按从上到下的顺序评估中间选择列表(带有变量赋值)。这种情况一直发生,但理论上并不能保证。
内部查询中的(高)limit
用于确保应用order by
子句,而不是实际限制任何内容。
变量@u和@p跟踪 user_id 和配置文件。根据以前的值,计算变量@g:只要 user_id 发生变化,它就会重置为1。否则,如果配置文件没有改变,它将保持相同的值,并且当配置文件确实改变时它会增加。
这样, grp 值可以按照降序时间戳的顺序识别配置文件相同且不间断的组。每个使用的最新组具有数字1,这是外部查询中唯一感兴趣的组。然后外部查询要求该组1具有多个记录(即同一个概要文件不止一次出现)。