shureen
Милорд Лось Кристофер
Иногда возникает ситуация (иногда у меня, иногда на форуме спрашивают), что нужно получить некоторые данные за месяц и вывести информацию по каждому дню. Например, нужно вывести календарь с указанием сколько товаров было добавлено каждый день, при этом в какие то дни товаров ваще не было добавлено. Обычно такое решается (ну по крайней мере я так решал) через PHP:
1) Узнаем месяц и год для которого нужен вывод
2) Узнаем сколько в месяце дней
3) По циклу проходимся и для каждого дня делаем выборку
Делать как говорится было нечего и решил написать сиё на mysql. Метод собственно для извращенцев, по другому его не назвать
Пример:
1) есть таблица товаров, с полями (products)
id | date_created и т.д.
2) Нужно вывести например статистику сколько добавлено по дням, например в апреле 2011
3) Решение
P.S. как и говорил для извращенцев
мож кому сиё пригодится
PSS. не нашёл как сделать подсвечивание sql кода
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
");

PSS. не нашёл как сделать подсвечивание sql кода