MySQL, подсчитывающий результаты в пределах диапазона и первое появление в любом диапазоне - PullRequest
2 голосов
/ 26 декабря 2011

Нужны советы о том, как лучше всего это сделать.Я пробовал примеры союзов, объединений и псевдонимов из нескольких вопросов о переполнении стека - ни один из них, кажется, не дает мне понять, куда я хочу пойти, не по своей вине.Я думаю, что я просто пытался решить эту проблему неправильно.

У меня есть одна таблица, в которой регистрируются все действия наших пользователей.Каждый журнал содержит столбец с идентификатором, а другой - с 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++;
        }

МИН (метка времени), указанная выше, захватывает первую метку времени в диапазоне - я хочузахватить первую временную метку независимо от диапазона.

Как я могу это сделать?

1 Ответ

1 голос
/ 26 декабря 2011

Ключ заключается в создании виртуальной производной таблицы, которая рассчитывает их первый доступ отдельно, а затем присоединяется к ней из вашего запроса, который возвращает записи за указанный период времени.

Ниже приведен код 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
...