【问题标题】:MySQL Counting Results Within a Range and First Occurance In Any RangeMySQL计数范围内的结果和任何范围内的第一次出现
【发布时间】:2012-01-27 17:13:00
【问题描述】:

寻找一些关于完成此任务的最佳方法的建议。我已经尝试了一些 Stack Overflow 问题中的 Unions、Joins 和 Alias 示例 - 似乎没有一个能让我到达我想去的地方,这不是他们的错。我想我只是想以错误的方式解决这个问题。

我有一张表格记录了我们用户的所有活动。每个日志包含一个带有 ID 的列和另一个带有 TIMESTAMP 的列。没有说明事件类型的列。

我要做的是在一个范围内抓取计数并附加一个带有激活日期(首次访问)的虚拟列,无论它是否在该范围内。对此的商业案例是,我希望有报告显示用户在某个范围内处于活动状态、他们的激活日期以及该范围内的事件数量。

它的 HTML 输出如下所示: 用户/范围内的总访问次数/首次访问(范围内或不在范围内)/最近访问次数(范围内)

我之所以能走到这一步,是因为这样做:

$result = mysql_query("
SELECT user, MIN(timestamp), MAX(timestamp), count(user) 
AS tagCount FROM " . $table . " 
WHERE date(timestamp) BETWEEN '" . $startdate . "' AND '" . $enddate . "'
GROUP BY user 
ORDER BY " . $orderby . " " . $order) or die(mysql_error()); 

然后我循环:

$i = 1;
while($row = mysql_fetch_array($result)){
    $user_name = str_replace("www.", "", $row['user']);  // removing www from usernames
        if( $i % 2 != 0) // used for alternating row colors
            $iclass = "row";
        else
            $iclass = "row-bg";
         echo  "<div class=\"" . $iclass . "\"><div class=\"number\">" . $i . "</div><div class=\"number\">" . $row['tagCount'] . "</div><div class=\"name\">" . "<a href=\"http://" . $row['user'] . "\" target=\"_blank\">"  . $server_name . "</a>" . "</div>" . "<div class=\"first\">" . $row['MIN(timestamp)'] . "</div><div class=\"recent\">" . $row['MAX(timestamp)'] . "</div></div>";    
                    $i++;
        }

上面的 MIN(timestamp) 抓取范围内的第一个时间戳 - 我想抓取第一个时间戳而不考虑范围。

我该怎么做?

【问题讨论】:

    标签: php mysql select join union


    【解决方案1】:

    关键是创建一个虚拟派生表,该表分别计算他们的第一次访问,然后从返回您指定时间段的记录的查询中加入它。

    以下是 SQL Server 代码,但我认为在 mysql 中也可以。如果没有,请告诉我,我将编辑语法。不管怎样,这个概念都是合理的。

    只需设置示例代码

    if object_id('tempdb..#eventlog') is not null
         drop table #eventlog
    
    
    create table #eventlog
    (
        userid int ,
        eventtimestamp datetime
    )
    
    insert #eventlog
    select 1,'2011-02-15'
    UNION
    select 1,'2011-02-16'
    UNION
    select 1,'2011-02-17'
    UNION
    select 2,'2011-04-18'
    UNION
    select 2,'2011-04-20'
    UNION
    select 2,'2011-04-21'
    
    declare @StartDate datetime
    declare @EndDate datetime
    
    set @StartDate = '02-16-2011'
    set @EndDate = '05-16-2011'
    

    这是可以解决您的问题的代码,您可以将#eventlog 替换为您的表名

    select e.userid,
            min(eventtimestamp)as FirstVisitInRange,
            max(eventtimestamp) as MostRecentVisitInRange,
            min(e2.FirstAccess) as FirstAccessEver,
            count(e.userid) as EventCountInRange
    from #eventlog e 
            inner join 
                (select userid,min(eventtimestamp) as FirstAccess
                      from #eventlog
                    group by userid
                  ) e2 on e.userid = e2.userid
       where 
              e.eventtimestamp between @StartDate and @EndDate
       group by e.userid
    

    【讨论】:

    • TetonSig,我确实了解了生成临时表的概念,但由于多个用户可能同时访问数据,我不得不将其与用户配置文件或会话相关联一些时尚。有没有办法在不添加表格的情况下做到这一点?
    • 临时表仅用于此处的示例,供我暂存一些示例数据。您可以使用现有表执行此操作,只需将 #eventlog 替换为您的表名即可。
    • TetonSig,我刚刚把它带回实验室,并且能够准确地创建所需的东西。我仍在努力了解您提出的语法,但这使我的学习速度加快了每小时几千英里。谢谢!
    • 不客气。随时与我聊天以提出问题。根本不是问题。如果您认为它已经解决了您的问题,请随时接受我的回答。
    猜你喜欢
    • 2017-05-21
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2015-09-16
    相关资源
    最近更新 更多