Рассчитать среднее время между публикацией и первым комментарием в двух таблицах MySQL - PullRequest
1 голос
/ 20 декабря 2011

Я столкнулся с этой (по крайней мере, для меня) проблемой:

У меня есть форум, где сообщения хранятся в таблице posts, а комментарии в таблице comments. Когда сообщение сделано, отметка времени сохраняется в столбце INT (11) posts.created_at. То же самое с комментарием ... когда комментарий сделан, с комментарием отметка времени сохраняется в comments.created_at.

Однако теперь я хотел бы знать среднее время в секундах, необходимое для появления первого комментария. Конечно, когда НЕТ комментариев, это не должно приниматься за среднее значение.

Можно ли это сделать одним SQL-запросом? Если нет, то как это можно сделать с наименьшим количеством запросов?

Надеюсь, у вас есть идея, как и у меня.

Ответы [ 3 ]

1 голос
/ 20 декабря 2011
select   posts.id,
         avg(comments.created_at - posts.created_at)
from     posts
join     comments
on       comments.id = posts.id
group by posts.id;

Это предполагает, что MySQL будет правильно обрабатывать арифметику даты и времени.

EDIT Как указывает @MattFellows, этот запрос некорректен, поскольку он группируется по почте;беру ли я min(comments.created_at) или нет.Действительно, результат, который он вернет, полностью избыточен: с min это будет время между каждым постом и его первым комментарием;без min это среднее время между публикацией и всеми комментариями (что является довольно ложной метрикой!) ... Я опускаю голову от стыда: P

Правильный запрос:

select avg(min(comments.created_at) - posts.created_at)
from   posts
join   comments
on     comments.id = posts.id;

Хотя, опять же, именно здесь метки времени являются числовыми, а не датой-временем, для которого (очевидно) MySQL не имеет перегруженных операторов.

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

Надеюсь, это сработает для вас:

select   avg(first_comments.first_time - posts.created_at)
from     posts
join    (select   comments.post_id
                  min(comments.created_at) as first_time
         from     comments
         group by post_id) as first_comments
on       first_comments.post_id = posts.id;
1 голос
/ 20 декабря 2011

Если вы использовали тип даты для полей даты, то что-то вроде:

SELECT AVG(
           DATEDIFF(MIN(comments.created_at), posts.created_at)
          ) 
FROM posts 
INNER JOIN comments on comments.post_primary_key = posts.primary_key

Должны ли вы получить то, что вам нужно

Но, как было отмечено в комментариях, вы не сохраняете даты как даты, помня об этом, попробуйте:

SELECT AVG(
           MIN(comments.created_at) - posts.created_at
          ) 
FROM posts 
INNER JOIN comments on comments.post_primary_key = posts.primary_key

Для полноты - мое последнее предложение ... Вы можете попробовать это:

SELECT AVG( sub.timeToComment ) 
FROM ( 
       SELECT MIN(comments.created_at) - posts.created_at as timeToComment 
       FROM posts 
       INNER JOIN comments on comments.post_primary_key = posts.primary_key
     ) as sub

Но не уверен, что это сильно отличается от подхода @Xophmeister

...