MySQL / PHP алгоритм для количества дней / выходных (в месяц) - PullRequest
1 голос
/ 17 июля 2009

Прежде чем я начну кодировать, я хочу сначала придумать хороший дизайн. По сути, у меня есть таблица базы данных, заполненная датами, и пользователи, связанные с этими датами (даты в формате sql).

Используя PHP, я хочу для каждого пользователя рассчитать (подсчитать в общем), сколько дней недели они связаны, а также сколько выходных они связаны. Мне нужно иметь общий счет за каждый месяц, а также общий итог. Это нужно для «запуска» с августа по май.

Я знаю, что могу определить, является ли день выходным или рабочим днем ​​с помощью:

 $date = '2007/08/30';
 $weekday = date('l', strtotime($date));

Для определения месяца я могу использовать SQL и использовать инструкцию case, например, для получения «October» из «10»:

 SELECT MONTH(DATE_SPECIFIED);

Однако я больше всего не уверен, через какой процесс пройти. Я мог бы легко иметь много запросов, но это неэффективно. В идеале я думал о печати результатов в HTML-таблице.

Может кто-нибудь предложить какие-либо предложения / советы о том, как вы могли бы сделать это?

Спасибо.


EDIT:

У меня есть таблица пользователей и таблица событий.

Вот таблица пользователей:

 CREATE TABLE `users` (
  `fname` varchar(50) NOT NULL,
  `lname` varchar(50) NOT NULL,
  `role` varchar(75) NOT NULL,
  `region` tinyint(4) unsigned default NULL,
  `username` varchar(25) NOT NULL,
  `password` varchar(75) NOT NULL,
  `new_pass` varchar(5) default NULL,
  PRIMARY KEY  (`username`),
  KEY `role` (`role`),
  KEY `region` (`region`),
  CONSTRAINT `users_ibfk_2` FOREIGN KEY (`region`) REFERENCES `region` (`region`) ON UPDATE CASCADE,
  CONSTRAINT `users_ibfk_1` FOREIGN KEY (`role`) REFERENCES `role` (`role`) ON UPDATE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8

А вот таблица событий:

 CREATE TABLE `eventcal` (
  `id` int(11) NOT NULL auto_increment,
  `region` tinyint(3) unsigned NOT NULL,
  `primary` varchar(25) NOT NULL,
  `secondary` tinyint(1) NOT NULL,
  `eventDate` date NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `primary_2` (`primary`),
  CONSTRAINT `eventcal_ibfk_1` FOREIGN KEY (`primary`) REFERENCES `users` (`username`) ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8

Обратите внимание, что evencal.primary имеет ссылку на внешний ключ для users.username ...

Ответы [ 2 ]

2 голосов
/ 17 июля 2009

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

SELECT MONTH(eventDate), DAYOFWEEK(eventDate), 
COUNT(*) 
FROM eventcal as e 
LEFT JOIN users as u ON e.primary = u.username 
GROUP BY MONTH(eventDate), DAYOFWEEK(eventDate);

Это должно вернуть нагрузку строк, 3 столбца до 7 строк в месяц. Один - это индекс дня (1 = воскресенье, 7 = суббота), один - числовой месяц, а один - число пользователей, прикрепленных к этому дню.

Если вам нужно ограничиться определенными месяцами, вы можете добавить предложение where, например ...

WHERE eventDate BETWEEN '20090501' AND '20091001'

Вы также можете использовать ключевое слово WITH ROLLUPS после группы, чтобы mysql возвращала итоги за день недели или за месяц. Но это часто сложнее, чем экономит, так как вам приходится писать логику, чтобы определить, является ли текущий ряд итоговым или нет.

EDIT:

Если вы хотите получить значения выходных / дня недели напрямую:

SELECT MONTH(eventDate), IF(WEEKDAY(eventDate)<5, 'weekday', 'weekend') AS DAY,
COUNT(*) 
FROM eventcal as e 
LEFT JOIN users as u ON e.primary = u.username 
GROUP BY MONTH(eventDate), IF(WEEKDAY(eventDate)<5, 'weekday', 'weekend');

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

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

2 голосов
/ 17 июля 2009

MySQL имеет функцию WEEKDAY ():

WEEKDAY (дата)

Возвращает индекс дня недели для даты (0 = Понедельник, 1 = вторник,… 6 = воскресенье).

Вы должны быть в состоянии использовать это в запросе MySQL с GROUP BY month.

Мои знания SQL очень ржавые, и я уверен, что это недопустимый SQL, но вы должны понять его.

SELECT user, weekdaysPerMonth, month
FROM
(SELECT COUNT(*) AS weekdaysPerMonth, user, date, month
 FROM table
 WHERE WEEKDAY(date) > 0 AND WEEKDAY(date) < 5)
GROUP BY month
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...