2009-07-16 7 views
1

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

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

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

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

Для определения месяца, я могу использовать SQL и использовать случай заявление, например, получить «Октябрь "от" 10 ":

SELECT MONTH(DATE_SPECIFIED); 

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

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

Спасибо.


EDIT:

У меня есть таблица пользователей, и 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 ...

+1

Можете ли вы поместить схему дб в? Мой ответ ниже предполагает, что у вас есть таблица пользователей, таблица дат и связь между ними ... – benlumley

+1

Хотя это также сработает, если бы у вас был только пользователь и таблица user_date – benlumley

ответ

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 eventDate BETWEEN '20090501' AND '20091001' 

Вы можете также использовать С накопительных ключевым словом после группы по 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 строки в месяц, один для рабочих дней, один в выходные дни.

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

+0

Спасибо за вашу помощь. Я просто разместил свою схему в редакторе. Я пытаюсь связать ваш пример с тем, что у меня есть. Единственная путаница в том, как обращаться с: LEFT JOIN users_dates ON date.id = users_dates.date_id – littleK

+1

обновил его в соответствии с вашей схемой – benlumley

+0

benlumley- Большое спасибо за вашу помощь. Оба SQL-предложения, которые вы предоставили, отлично работают! Кажется, что вы действительно можете группироваться по значению calc. Я собираюсь использовать второе. Еще раз спасибо! – littleK

2

У MySQL есть функция WEEKDAY():

WEEKDAY (дата)

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

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

Знание 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 
Смежные вопросы