MySQL группа, имеющая вопрос - PullRequest
0 голосов
/ 06 апреля 2011

У меня есть простая таблица MySQL, такая как:

create table `users`( 
   `id` int(5) NOT NULL AUTO_INCREMENT , 
   `user` varchar(100) NOT NULL , 
   `registration_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP , 
   PRIMARY KEY (`id`)
 )

, и мне интересно, как мне получить count зарегистрированных пользователей:

  • сегодня
  • на этой неделе
  • в этом месяце

и есть ли способ сделать это в одном запросе?

Ответы [ 5 ]

2 голосов
/ 06 апреля 2011

Предполагая, что понедельник - начало недели, используйте:

SELECT SUM(CASE 
             WHEN FROM_UNIXTIME(u.registration_date, '%Y-%m-%d') = CURDATE() THEN 1 
             ELSE 0 
           END) AS numToday,
       SUM(CASE 
             WHEN FROM_UNIXTIME(u.registration_date, '%Y-%m-%d') BETWEEN DATE_ADD(CURDATE(), INTERVAL 0-WEEKDAY(CURDATE()) DAY)AND CURDATE() THEN 1 
             ELSE 0 
           END) AS numThisWeek,
       SUM(CASE 
             WHEN FROM_UNIXTIME(u.registration_date, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m') THEN 1 
             ELSE 0 
           END) AS numThisMonth
  FROM USERS u

Хотя из-за использования FROM_UNIXTIME он не сможет использовать индекс, если он существует в столбце registration_date. Однако вы можете изменить логику, чтобы применить функцию UNIX_TIMESTAMP к значениям дат, по которым производится фильтрация.

2 голосов
/ 06 апреля 2011

Вы можете написать отдельные подзапросы и объединить результаты для окончательного ответа.

SELECT NumToday, NumThisWeek, NumThisMonth 
   FROM
      (SELECT COUNT(*) AS NumToday FROM `users` 
          WHERE date(`registration_date`) = date(now()) 
   JOIN 
      (SELECT COUNT(*) AS NumThisWeek FROM `users` 
          WHERE week(`registration_date`) = week(now()) AND year(`registration_date`) = year(now()))
   JOIN
      (SELECT COUNT(*) AS NumThisMonth FROM `users` 
          WHERE month(`registration_date`) = month(now()) AND year(`registration_date`) = year(now()))
1 голос
/ 06 апреля 2011

если вам нужны последние 7 дней и последние 30 дней (не считая начала недели или начала месяца)

вы можете сделать в одном запросе, как это

SELECT 
SUM(IF(DATEDIFF(NOW(),registration_date) < 1 , 1 ,0))  AS thisday ,
SUM(IF(DATEDIFF(NOW(),registration_date) < 8  AND DATEDIFF(NOW(),registration_date) > 0 ,1,0))  AS last7day ,
SUM(IF(DATEDIFF(NOW(),registration_date) < 31 AND DATEDIFF(NOW(),registration_date) > 7 ,1,0))  AS last30day 
FROM users 
WHERE DATEDIFF(NOW(),registration_date) < 31
0 голосов
/ 06 апреля 2011

Вы можете группировать по дате (без времени), чтобы получить счет сегодня, Вы можете группировать по дате и части недели или месяца, чтобы получить соответствующий запрос

например (подсчет за сегодня):

Выберите количество (*) из [таблицы] сгруппировать по [date_column] имеющий [date_column] = getdate ()

0 голосов
/ 06 апреля 2011
SELECT COUNT(*) FROM `users` WHERE `registration_date` >  DATE_SUB(NOW(),INTERVAL 1 DAY)
SELECT COUNT(*) FROM `users` WHERE `registration_date` >  DATE_SUB(NOW(),INTERVAL 1 WEEK)
SELECT COUNT(*) FROM `users` WHERE `registration_date` >  DATE_SUB(NOW(),INTERVAL 1 MONTH)

Я думаю, это будет правильно. еще не проверял.

...