Vamos a ver si se entiende la idea...
Creo una tabla basica de ventas:
Código SQL:
Ver originalmysql> CREATE TABLE ventas(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, fecha datetime, importe DECIMAL(14,3));
Query OK, 0 ROWS affected (0.23 sec)
Inserto algunas pocas ventas:
Código SQL:
Ver originalmysql> INSERT INTO ventas(fecha, importe)
-> VALUES('2017-01-11 17:45:00', 1234.21),
-> ('2017-03-11 13:45:00', 1234.21),
-> ('2017-11-11 17:45:00', 1234.21);
Query OK, 3 ROWS affected (0.10 sec)
Records: 3 Duplicates: 0 Warnings: 0
Creo una tabla de meses:
Código SQL:
Ver originalmysql> CREATE TABLE meses(nro_mes SMALLINT PRIMARY KEY, nombre_mes VARCHAR(100));
Query OK, 0 ROWS affected (0.24 sec)
La lleno con los meses:
Código SQL:
Ver originalmysql> INSERT INTO meses
-> VALUES (1, 'Enero'),
-> (2, 'Febrero'),
-> (3, 'Marzo'),
-> (4, 'Abril'),
-> (5, 'Mayo'),
-> (6, 'Junio'),
-> (7, 'Julio'),
-> (8, 'Agosto'),
-> (9, 'Septiembre'),
-> (10, 'Octubre'),
-> (11, 'Noviembre'),
-> (12, 'Diciembre');
Query OK, 12 ROWS affected (0.05 sec)
Records: 12 Duplicates: 0 Warnings: 0
Hago una consulta usando la funcion IFNULL para poner ceros donde no hay datos:
Código SQL:
Ver originalmysql> SELECT 2017 Anio, nro_mes Mes, IFNULL(importe, 0.0) importe
-> FROM meses M LEFT JOIN ventas V ON M.nro_mes = MONTH(fecha);
+------+-----+----------+
| Anio | Mes | importe |
+------+-----+----------+
| 2017 | 1 | 1234.210 |
| 2017 | 2 | 0.000 |
| 2017 | 3 | 1234.210 |
| 2017 | 4 | 0.000 |
| 2017 | 5 | 0.000 |
| 2017 | 6 | 0.000 |
| 2017 | 7 | 0.000 |
| 2017 | 8 | 0.000 |
| 2017 | 9 | 0.000 |
| 2017 | 10 | 0.000 |
| 2017 | 11 | 1234.210 |
| 2017 | 12 | 0.000 |
+------+-----+----------+
12 ROWS IN SET (0.00 sec)
Esa es la idea básica, que puedes combinar como desees.
¿Queda mas claro así?