Привет.
Вот пример того, что вы хотите.
Алгоритм такой же как описал Максим. По другому можно с юнионами, но там границы месяца будут не точные.
-- Генерируем временную таблицу с датами для примера
CREATE TEMPORARY TABLE temp_t (tdate DATE);
INSERT INTO temp_t (tdate) VALUES ('2015-09-02');
INSERT INTO temp_t (tdate) VALUES ('2015-09-02');
INSERT INTO temp_t (tdate) VALUES ('2015-09-05');
INSERT INTO temp_t (tdate) VALUES ('2015-09-05');
INSERT INTO temp_t (tdate) VALUES ('2015-09-07');
-- Пишим процедуру генерации дней. На вход идет дата и по ней генерируется таблица с 1 по последний день месяца этой даты
DROP PROCEDURE IF EXISTS buildMonthTable;
DELIMITER $$
CREATE PROCEDURE buildMonthTable(IN indate DATE)
BEGIN
DECLARE lastday DATE DEFAULT LAST_DAY(indate);
DECLARE startday DATE DEFAULT DATE_ADD(indate, INTERVAL - DAYOFMONTH(indate) +1 DAY);
DROP TABLE IF EXISTS temp_month_days;
CREATE TEMPORARY TABLE temp_month_days (mday DATE);
WHILE (lastday >= startday) DO
INSERT INTO temp_month_days VALUES (startday);
SET startday = DATE(DATE_ADD(startday, INTERVAL +1 DAY));
END WHILE;
END$$
DELIMITER;
-- Вызываем процедуру для генерации таблицы для текущего месяца
CALL buildMonthTable(CURDATE())
-- Соединяем две таблицы и группируем по датам
SELECT tm.mday, COUNT(tt.tdate) AS COUNT FROM temp_month_days AS tm
LEFT JOIN temp_t tt ON tm.mday = tt.tdate
GROUP BY tm.mday
PS: такая генерация почему-то занимает некоторое время. Хотя, вроде, небольшая табличка.