GROUP BY DAY(FROM_UNIXTIME) 意外更改计数

Posted

技术标签:

【中文标题】GROUP BY DAY(FROM_UNIXTIME) 意外更改计数【英文标题】:GROUP BY DAY(FROM_UNIXTIME) unexpectedly changes count 【发布时间】:2013-06-20 16:44:26 【问题描述】:

我将各个网站访问的会话 ID、IP 地址和时间戳以及所有相关的综合浏览量存储在数据库中。它包含更多数据,但此处相关的数据是通过此查询提取的:

SELECT 
Pageviews.id, Visitors.time, Visitors.session, Visitors.ip
FROM Visitors
INNER JOIN Pageviews
    ON Visitors.session=Pageviews.session
ORDER BY Visitors.time ASC

结果如下:

id      time        session                     ip

1048    1371473496  nhie5sh2tiufs2ufupcremc6c2  x88.xxx.xxx.xxx
1050    1371474103  8hfphqvq5ri6muc84oidp7q195  x6x.xxx.xxx.xxx
1062    1371474956  hhgs-s-r4v26pjbilkg8d81olqj7  xxx.x3x.xxx.xxx
1066    1371476339  ic8iqd0a4mpoelni15n4tq3404  x1x.xxx.xxx.xxx
1067    1371476629  ockivrm61upk7ss5ni4n8muv23  x2x.xxx.xxx.xxx
1070    1371477856  5tdj9rrd1qsvafovufnkgh8r26  xxx.xxx.x7x.xxx
1068    1371477856  5tdj9rrd1qsvafovufnkgh8r26  xxx.xxx.xxx.x2x
1069    1371478229  5e82v29nuf2k46ir13i21msps5  xxx.x5x.xxx.x8x

为了获取访问者(不同的 IP)、访问量(不同的会话)和浏览量(不同的浏览量 ID)的总数,我查询数据库如下:

SELECT 
 count(distinct(Visitors.ip)) as 'Visitors',
 count(distinct(Visitors.session)) as 'Visits',
 count(Pageviews.id) as 'Pageviews'
FROM Visitors
INNER JOIN Pageviews
 ON Visitors.session=Pageviews.session

返回如下内容:

Visitors   Visits    Pageviews

211        244       412

但是,我想使用存储的时间戳按年、月和日对这些总数进行分组。为了获取这些数据,我编写了以下查询:

SELECT 
 DAY(FROM_UNIXTIME(Visitors.time)) as 'Day',
 MONTH(FROM_UNIXTIME(Visitors.time)) as 'Month',
 YEAR(FROM_UNIXTIME(Visitors.time)) as 'Year',
 count(distinct(Visitors.ip)) as 'Visitors',
 count(distinct(Visitors.session)) as 'Visits',
 count(Pageviews.id) as 'Pageviews'
FROM Visitors
INNER JOIN Pageviews
 ON Visitors.session=Pageviews.session
GROUP BY Year, Month, Day
ORDER BY Year, Month, Day DESC

这很有效,因为日期、浏览量和访问量都是正确的:

Day Month   Year    Visitors    Visits  Pageviews

20  6       2013    40          43      59
19  6       2013    80          90      112
18  6       2013    62          66      173
17  6       2013    43          45      68

如您所见,此处的综合浏览量加起来为 412,访问量为 244。然而,让我彻夜难眠的是,访问者数加起来不等于 211,因为它应该,但改为 225。我不明白为什么这只发生在访问者人数上。

很抱歉这个冗长的问题。任何想法将不胜感激。

【问题讨论】:

附注:distinct 不是一个函数。写distinct(foo)distinct foo 相同。括号完全没用,并且经常暗示(尤其是在与多列一起使用时)distinct 的行为被误解了。 很高兴知道,谢谢。 【参考方案1】:

由于您计算的是 DISTINCT IP,因此当您按月 GROUP BY 时,每个分组(月)都会获得 DISTINCT IP 的计数,即,如果人们在多个月内访问,则可以多次计算。

例如:12.123.456.78 访问量在 3 月和 4 月,即每个月统计一个 Distinct IP,但如果不按月分组,则只有 1 个不同 IP,不能简单地将分组 COUNT(DISTINCT) 的结果相加获取未分组时的总 COUNT(DISTINCT)。

此功能可能会有所帮助,因为它可以揭示重复访问者与新访问者的区别。

【讨论】:

啊,当然!进一步阅读,这显然被称为“酒店问题”。

以上是关于GROUP BY DAY(FROM_UNIXTIME) 意外更改计数的主要内容,如果未能解决你的问题,请参考以下文章

GROUP BY DAY(FROM_UNIXTIME) 意外更改计数

sqlAlchemy 按DateTime字段的年或月进行group_by查询

GROUP BY + CASE 语句

GROUP BY TRUNC 的链(日期)

MySQL笔记-group by和聚合函数的使用

Left Join with same table and group by 以相反的顺序返回重复的元组