假设我有一个表记录每个用户拥有IP地址(ipaddr)的传入用户。
选择之前从未访问过网站的所有用户的最佳方法是什么? (因此特定的IPADDR值仅存在于一次表中),但我只想知道过去6小时内新访问者的数量。
我基本上想在SQL中做这样的事情:
SELECT * from visitors GROUP BY ipaddr WHERE COUNT(ipaddr) = 1 and date > '2011-03-31 00:59:11'
但是,DATE条件应该仅适用于结果,而不是用于检查访问者是否是新的。
更新:
有一个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地址有2个不同的SID属于它,因此不是新访问者。
查询的结果应该没有上面列出的任何行,看看此访问者在数据库中有两个会话。如果删除了最后一行(使用sid 694387538590),则访问者应成为新访问者并显示在查询中。
答案 0 :(得分:5)
"WHERE"
的{{1}}为GROUP BY
:
HAVING
SELECT ipaddr from visitors
GROUP BY ipaddr
HAVING COUNT(ipaddr) = 1 AND MIN(date) > '2011-03-31 00:59:11'
<强>解释强>
SELECT ipaddr, max(sid) sid
FROM visitors
GROUP BY ipaddr
HAVING COUNT(DISTINCT sid) = 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
子句 GROUP BY
在GROUP BY中使用,但未在ipaddr
中使用。还要sid
我使用了MAX,但请记住它只会应用于当前sid
的行组,并且由于查询中的条件有1个唯一ipaddr
但重复结果将是sid