Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于从数据库返回新访问者的MySQL查询_Mysql_Optimization - Fatal编程技术网

用于从数据库返回新访问者的MySQL查询

用于从数据库返回新访问者的MySQL查询,mysql,optimization,Mysql,Optimization,假设我有一个记录传入用户的表,其中每个用户都有一个IP地址(ipaddr) 选择以前从未访问过该网站的所有用户的最佳方式是什么?(因此特定的IPADDR值只在表中存在一次),但是我只想知道过去6小时内新来的访客的情况 我基本上希望在SQL中执行类似的操作: SELECT * from visitors GROUP BY ipaddr WHERE COUNT(ipaddr) = 1 and date > '2011-03-31 00:59:11' 但是,日期条件应仅适用于结果,而不适用于检

假设我有一个记录传入用户的表,其中每个用户都有一个IP地址(ipaddr)

选择以前从未访问过该网站的所有用户的最佳方式是什么?(因此特定的IPADDR值只在表中存在一次),但是我只想知道过去6小时内新来的访客的情况

我基本上希望在SQL中执行类似的操作:

SELECT * from visitors GROUP BY ipaddr WHERE COUNT(ipaddr) = 1 and date > '2011-03-31 00:59:11'
但是,日期条件应仅适用于结果,而不适用于检查访客是否为新访客

更新:

有一个SID字段用于说明用户浏览会话

以下是相关的表架构:

CREATE TABLE `visitors` (
  `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `sid` bigint(12) unsigned NOT NULL,
  `ipaddr` int(8) NOT NULL,
)
一些示例数据:

INSERT INTO `visitors` (`date`,`sid`, `ipaddr`)
VALUES
    ('2011-03-31 06:25:48', 299521885457, -1454342140);


INSERT INTO `visitors` (`date`,`sid`, `ipaddr`)
VALUES
    ('2011-03-31 06:26:37', 299521885457, -1454342140);


INSERT INTO `visitors` (`date`,`sid`, `ipaddr`)
VALUES
    ('2010-01-01 15:23:44', 694387538590, -1454342140);
此访问者有两行用于实时执行当前会话,每行用于他访问过的每个页面(仅显示相关架构)。显示的最后一个示例行是2010年的访问,这意味着该ip地址有两个不同的SID属于它,因此不是新的访问者

查询的结果不应该包含上面列出的任何一行,因为这个访问者在数据库中有两个会话。如果删除了最后一行(sid为694387538590),则访问者应成为新访问者并出现在查询中。

其中
分组依据的
具有

SELECT ipaddr from visitors
GROUP BY ipaddr
HAVING COUNT(ipaddr) = 1 AND MIN(date) > '2011-03-31 00:59:11'
更新 说明:

SELECT date, sid, ipaddr FROM visitors

date                sid        ipaddr 
------------------------------------------
2011-03-31 06:25:48 299525457  -1454342140 
2011-03-31 06:26:37 299525457  -1454342140 
2010-01-01 15:23:44 694388590  -1454342140 
2011-03-31 11:23:44 111111111  -1234444811 
2011-03-31 12:23:44 111111111  -1234444811

SELECT ipaddr FROM visitors GROUP BY ipaddr

ipaddr
-----------
-1454342140 
-1234444811 

--- group for ip -1454342140 ---

2011-03-31 06:25:48 299525457  -1454342140 
2011-03-31 06:26:37 299525457  -1454342140 
2010-01-01 15:23:44 694388590  -1454342140

COUNT(DISTINCT sid) = COUNT(299525457, 694388590) = 2
--> there is more than 1 session for this ip: not good!!!

  ==> group discarded

--- group for ip -1234444811 ---

2011-03-31 11:23:44 111111111  -1234444811 
2011-03-31 12:23:44 111111111  -1234444811

COUNT(DISTINCT sid) = COUNT(111111111) = 1 --> OK
(here COUNT(sid) = count(111111111, 111111111) = 2
 --> despite it is the same sid, the count is 2, that is why using DISTINCT)

MIN(date) = '2011-03-31 11:23:44' > '2011-03-31 00:59:11' --> OK

  ==> group accepted
SELECT
中的授权列包括:

  • 分组依据
    子句中使用的列
  • 其他柱子的一个门

ipaddr
在组中使用,而不是
sid
。为了也有
sid
,我使用了MAX,但请记住,它将仅应用于当前
ipaddr
的行组,并且由于查询中的条件,有1个唯一的
sid
,但会重复,因此结果将是
sid

Hmm这似乎与我描述的一样。你能解释一下这个查询是如何工作的吗?我认为GROUP BY是在拥有之前应用的,因此GROUP BY将为每个IPADR留下1行。那么,对于GROUP BY之后剩下的所有行,count(ipaddr)不是等于1吗?HAVING子句用于过滤聚合(SUM、count、AVG),WHERE子句根据条件过滤。因此它首先按分组,然后消除所有不符合HAVING条件的记录。
HAVING
子句与聚合函数一起使用,以筛选由
GROUP BY
生成的组,即:在返回
IPADR
之前,
计数(IPADR)=1
是根据具有
ipaddr
的行组进行评估的。谢谢大家,这非常有用!在IPADDR上有一个索引有意义吗,或者不使用该索引有意义吗?
SELECT date, sid, ipaddr FROM visitors

date                sid        ipaddr 
------------------------------------------
2011-03-31 06:25:48 299525457  -1454342140 
2011-03-31 06:26:37 299525457  -1454342140 
2010-01-01 15:23:44 694388590  -1454342140 
2011-03-31 11:23:44 111111111  -1234444811 
2011-03-31 12:23:44 111111111  -1234444811

SELECT ipaddr FROM visitors GROUP BY ipaddr

ipaddr
-----------
-1454342140 
-1234444811 

--- group for ip -1454342140 ---

2011-03-31 06:25:48 299525457  -1454342140 
2011-03-31 06:26:37 299525457  -1454342140 
2010-01-01 15:23:44 694388590  -1454342140

COUNT(DISTINCT sid) = COUNT(299525457, 694388590) = 2
--> there is more than 1 session for this ip: not good!!!

  ==> group discarded

--- group for ip -1234444811 ---

2011-03-31 11:23:44 111111111  -1234444811 
2011-03-31 12:23:44 111111111  -1234444811

COUNT(DISTINCT sid) = COUNT(111111111) = 1 --> OK
(here COUNT(sid) = count(111111111, 111111111) = 2
 --> despite it is the same sid, the count is 2, that is why using DISTINCT)

MIN(date) = '2011-03-31 11:23:44' > '2011-03-31 00:59:11' --> OK

  ==> group accepted