Mysql 在数据库中分离新用户和返回的用户
我有一个相当大的DB,但为了这个问题,我简化了它: 基本上,每次用户在我的站点上单击某个内容时,它都会作为一行记录在我的数据库中:UserID字段是用于标识用户的cookie,而Stuff和MoreStuff是关于单击的数据。请注意,很明显,它们可能每次都不同,Foo和Bar只是一种表示 我想做的是:使用SQL查询,过滤掉所有的第一次访问,或者我假设的所有重复访问,如果我可以做一次,我可以为另一次反向过滤。因此,如果我要过滤掉样本中的所有重复访问,我会得到以下结果: 绿色表示选中的行,红色表示被拒绝的行Mysql 在数据库中分离新用户和返回的用户,mysql,sql,database,Mysql,Sql,Database,我有一个相当大的DB,但为了这个问题,我简化了它: 基本上,每次用户在我的站点上单击某个内容时,它都会作为一行记录在我的数据库中:UserID字段是用于标识用户的cookie,而Stuff和MoreStuff是关于单击的数据。请注意,很明显,它们可能每次都不同,Foo和Bar只是一种表示 我想做的是:使用SQL查询,过滤掉所有的第一次访问,或者我假设的所有重复访问,如果我可以做一次,我可以为另一次反向过滤。因此,如果我要过滤掉样本中的所有重复访问,我会得到以下结果: 绿色表示选中的行,红色表示被
仅使用SQL如何实现这一点?您可以使用聚合函数COUNT,然后使用如下语句:
SELECT userID, COUNT(userID)
FROM tbl
GROUP BY userID
HAVING COUNT(userID) >= 2
如果您想筛选出哪些是重复访客,则可以重复使用上述查询,如:
SELECT * FROM tbl
WHERE EXISTS
(
SELECT userID, COUNT(userID)
FROM tbl
GROUP BY userID
HAVING COUNT(userID) >= 2
)
GROUP BY userID
如果您想看到第一次访客,可以将COUNTuserID>=2改为COUNTuserID=1,当然也可以使用notexists代替EXISTS
请参见您可以使用聚合函数COUNT,然后使用如下语句:
SELECT userID, COUNT(userID)
FROM tbl
GROUP BY userID
HAVING COUNT(userID) >= 2
如果您想筛选出哪些是重复访客,则可以重复使用上述查询,如:
SELECT * FROM tbl
WHERE EXISTS
(
SELECT userID, COUNT(userID)
FROM tbl
GROUP BY userID
HAVING COUNT(userID) >= 2
)
GROUP BY userID
如果您想看到第一次访客,可以将COUNTuserID>=2改为COUNTuserID=1,当然也可以使用notexists代替EXISTS
如果您只想进行第一次访问,请参见:
select t.*
from table t
where not exists (select 1
from table t2
where t2.id = t.id and t2.timestamp < t.timestamp
);
这表示:从表中获取所有行,其中没有具有相同id和更小时间戳的行。这相当于为每个id获取最小值
为了提高性能,您需要在tableid、timestamp上建立索引。如果您只需要第一次访问:
select t.*
from table t
where not exists (select 1
from table t2
where t2.id = t.id and t2.timestamp < t.timestamp
);
这表示:从表中获取所有行,其中没有具有相同id和更小时间戳的行。这相当于为每个id获取最小值
为了提高性能,您需要在tableid、timestamp上建立索引。您可以通过GROUPBY和mintimestamp表来实现这一点。然后将其放入视图或临时别名表中并联接
示例-获取首次访问时间戳:
SELECT userID,
min(TIMESTAMP)
FROM info
GROUP BY userID
示例-获取所有信息:
SELECT *
FROM info t,
(SELECT userID,
min(TIMESTAMP) as timestamp
FROM info
GROUP BY userID) AS t2
WHERE t.userID = t2.userID
AND t.TIMESTAMP = t2.TIMESTAMP;
SQLFiddle:您可以使用GROUPBY和mintimestamp表来完成此操作。然后将其放入视图或临时别名表中并联接
示例-获取首次访问时间戳:
SELECT userID,
min(TIMESTAMP)
FROM info
GROUP BY userID
示例-获取所有信息:
SELECT *
FROM info t,
(SELECT userID,
min(TIMESTAMP) as timestamp
FROM info
GROUP BY userID) AS t2
WHERE t.userID = t2.userID
AND t.TIMESTAMP = t2.TIMESTAMP;
SQLFiddle:实际表是否包含指示记录输入时间的字段?哦,是的,对不起。有一个时间戳列。编辑…实际表格是否包含一个字段,指示记录是何时输入的?哦,是的,对不起。有一个时间戳列。正在编辑…SQL中存在错误。您的SQL相当于按用户ID从tbl组中选择*。请参见:此外,如果有效,则假定插入顺序为实际点击顺序。如果MySQL或webapp以任何方式延迟,则顺序可能与实际时间戳不同。另一个问题是,如果两次单击由于AJAX延迟而具有相同的时间戳,该怎么办。非常非常不可能。。。但值得一提的是弱点。测试:sqlfiddle.com/!2/4b475/3@maythesource.com:在你第一次发表评论时,你错了我的第二个SQL。它不应该不存在…COUNTuserID=1,但不存在…COUNTuserID>=2。然而,在你的第二条评论中,我认为他是在寻找第一次访问者,而不是用户访问的第一次日期?但你可以在这一点上正确。如果是这样的话,MINtimestamp函数就是正确的。您的子查询不依赖于外部查询。这相当于按用户ID从tbl组中选择*。此外,依赖默认的mysql排序是非常糟糕的做法。@Bluefire请查看注释和链接。另外:SQL中有一个错误。您的SQL相当于按用户ID从tbl组中选择*。请参见:此外,如果有效,则假定插入顺序为实际点击顺序。如果MySQL或webapp以任何方式延迟,则顺序可能与实际时间戳不同。另一个问题是,如果两次单击由于AJAX延迟而具有相同的时间戳,该怎么办。非常非常不可能。。。但值得一提的是弱点。测试:sqlfiddle.com/!2/4b475/3@maythesource.com:在你第一次发表评论时,你错了我的第二个SQL。它不应该不存在…COUNTuserID=1,但不存在…COUNTuserID>=2。然而,在你的第二条评论中,我认为他是在寻找第一次访问者,而不是用户访问的第一次日期?但你可以在这一点上正确。如果是这样的话,MINtimestamp函数就是正确的。您的子查询不依赖于外部查询。这相当于按用户ID从tbl组中选择*。此外,依赖默认的mysql排序是非常糟糕的做法。@Bluefire请查看注释和链接。也: