用于工作日/周末计数的MySQL / PHP算法(每月)

时间:2009-07-16 22:04:24

标签: php mysql algorithm date

在开始编码之前,我想首先想出一个好的设计。基本上,我有一个填充日期的数据库表,以及与这些日期相关联的用户(日期是sql格式)。

使用PHP我想为每个用户计算(总计)他们与之相关的工作日数,以及他们与之相关的周末数。我需要每个月有一个总数,以及总数。这需要从8月到5月“运行”。

我知道我可以确定一天是周末还是工作日:

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

为了确定月份,我可以使用SQL,并使用case语句,例如,从“10”获取“October”:

 SELECT MONTH(DATE_SPECIFIED);

但我最不确定的是要经历的过程。我可以很容易地进行大量查询,但效率很低。理想情况下,我正在考虑在html表中打印结果。

任何人都可以就如何进行提出任何建议/建议吗?

感谢。


编辑:

我有一个用户表和一个eventcal表。

以下是用户表:

 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

这是eventcal表:

 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 个答案:

答案 0 :(得分:2)

MySQL有一个WEEKDAY()函数:

  

WEEKDAY(日期)

     

返回date的工作日索引(0   =星期一,1 =星期二,... 6 =星期天)。

您应该能够在GROUP BY月的MySQL查询中使用它。

我的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

答案 1 :(得分:2)

你应该可以....(假设你有一个日期表,一个用户表和一个链接表)

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'

您还可以在group by之后使用WITH ROLLUPS关键字让mysql返回每周或每月的总计。但这通常比使用它更麻烦,因为你必须编写逻辑来确定当前行是否为总数。

编辑:

如果您想直接获取周末/工作日值:

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行,一个是工作日,一个是周末。

(虽然我不能完全确定你可以用这样的计算值进行分组,但我想你可以 - 如果你尝试的话请告诉我!)