Календарь для извращенцев :)

shureen

Милорд Лось Кристофер
Иногда возникает ситуация (иногда у меня, иногда на форуме спрашивают), что нужно получить некоторые данные за месяц и вывести информацию по каждому дню. Например, нужно вывести календарь с указанием сколько товаров было добавлено каждый день, при этом в какие то дни товаров ваще не было добавлено. Обычно такое решается (ну по крайней мере я так решал) через PHP:
1) Узнаем месяц и год для которого нужен вывод
2) Узнаем сколько в месяце дней
3) По циклу проходимся и для каждого дня делаем выборку

Делать как говорится было нечего и решил написать сиё на mysql. Метод собственно для извращенцев, по другому его не назвать :)
Код:
delimiter //

DROP FUNCTION IF EXISTS get_rus_month//

CREATE FUNCTION get_rus_month(day_number INT)

RETURNS VARCHAR(32)

BEGIN

	CASE day_number

		WHEN 1 THEN RETURN "понедельник";

		WHEN 2 THEN RETURN "вторник";

		WHEN 3 THEN RETURN "среда";

		WHEN 4 THEN RETURN "четверг";

		WHEN 5 THEN RETURN "пятница";

		WHEN 6 THEN RETURN "суббота";

		WHEN 7 THEN RETURN "воскресенье";

	END CASE;

END//



DROP FUNCTION IF EXISTS calendar//

CREATE FUNCTION calendar(_month int(2), _year int(4))

RETURNS TEXT

BEGIN

	DECLARE sql_text TEXT DEFAULT "";

	DECLARE count_days_in_mounth INT(2);

	DECLARE i INT(2) DEFAULT 1;

	DECLARE day_of_week INT(2);

	DECLARE start_i INT(2);

	SET count_days_in_mounth = (UNIX_TIMESTAMP(CONCAT(_year, "-", _month, "-01") + INTERVAL 1 MONTH) - UNIX_TIMESTAMP(CONCAT(_year, "-", _month, "-01"))) / 24 / 60 / 60;

	WHILE i <= count_days_in_mounth DO

		SET day_of_week = DATE_FORMAT(CONCAT(_year, "-", _month, "-", i), "%w");

		SET sql_text = CONCAT(sql_text, "SELECT ", i, " as day, ", _month, " as month, ", _year, " as year, \"", get_rus_month(IF(day_of_week = 0, 7, day_of_week)), "\" as day_of_week");

		SET sql_text = CONCAT(sql_text, IF(i < count_days_in_mounth, " UNION ", ""));

		SET i = i + 1;

	END WHILE;

	RETURN sql_text;

END//



DROP PROCEDURE IF EXISTS query_from_calendar//

CREATE PROCEDURE query_from_calendar(IN _month int(2), IN _year int(4), IN query LONGTEXT)

BEGIN

	SET @query_text = REPLACE(query, "%calendar_table%", CONCAT("(", calendar(_month, _year), ")"));

	PREPARE calendar_table FROM @query_text;

	EXECUTE calendar_table;

END//
:) Пример:
1) есть таблица товаров, с полями (products)
id | date_created и т.д.
2) Нужно вывести например статистику сколько добавлено по дням, например в апреле 2011
3) Решение :)
Код:
CALL query_from_calendar(4, 2011, "

SELECT

	c.*,

	COUNT(p.id) as product_count

FROM

	%calendar_table% c

LEFT JOIN

	products p

ON

	DATE_FORMAT(p.date_created, \"%e-%c-%Y\") = CONCAT(c.day, \"-\", c.month, \"-\", c.year)

GROUP BY

	c.day

");
P.S. как и говорил для извращенцев :) мож кому сиё пригодится
PSS. не нашёл как сделать подсвечивание sql кода
 
Сверху