Digamos que tengo una tabla de "ventas" como abajo
Customer Date Amount
Paul 15/01/2015 2000
Jonathan 15/01/2015 3000
Taylor 15/01/2015 2000
Mark 15/01/2015 3000
Paul 15/02/2015 2000
Jonathan 15/02/2015 3000
Paul 25/02/2015 4000
Jonathan 25/02/2015 5000
Jonathan 15/03/2015 2000
Jonathan 25/04/2015 5000
Taylor 25/04/2015 4000
Mark 25/04/2015 5000
Paul 25/05/2015 4000
Jonathan 25/05/2015 5000
Taylor 25/05/2015 4000
Mark 25/05/2015 5000
Y en el informe quiero verlo como abajo -
Customer Month Amount
Paul 201501 2000
Paul 201502 6000
Paul 201503 0
Paul 201504 0
Paul 201505 4000
¿Por favor, dime cómo hacerlo?
Actualizar
Customer Month Amount
Paul 201501 2000
Paul 201502 6000
Paul 201503 0
Paul 201504 0
Paul 201505 4000
Jonathan 201501 3000
Jonathan 201502 8000
Jonathan 201503 2000
Jonathan 201504 5000
Jonathan 201505 5000
Taylor 201501 2000
Taylor 201502 0
Taylor 201503 0
Taylor 201504 4000
Taylor 201505 4000
Mark 201501 3000
Mark 201502 0
Mark 201503 0
Mark 201504 5000
Mark 201505 5000
También necesito hacer esta vista para todos los clientes. Por favor, dime cómo hacer eso.
Respuestas
1 para la respuesta № 1Aquí hay una solución, con una demostración, usando la fecha que proporcionó. Además, se agregan más datos para la simulación.
caída de ventas de mesa;
SQL:
-- data
create table sales(Customer varchar(100), `Date` date, Amount int);
insert into sales values
("Paul", "2015-01-15", 2000),
("Jonathan", "2015-01-15", 3000),
("Taylor", "2015-01-15", 2000),
("Mark", "2015-01-15", 3000),
("Paul", "2015-02-15", 2000),
("Jonathan", "2015-02-15", 3000),
("Paul", "2015-02-25", 4000),
("Jonathan", "2015-02-25", 5000),
("Jonathan", "2015-03-15", 2000),
("Jonathan", "2015-04-15", 5000),
("Taylor", "2015-04-25", 4000),
("Mark", "2015-04-25", 5000),
("Paul", "2015-05-25", 4000),
("Jonathan", "2015-05-25", 5000),
("Taylor", "2015-05-25", 4000),
("Mark", "2015-05-25", 5000);
select * from sales;
-- query wanted
select
COALESCE(s.Customer, "") AS Customer, DATE_FORMAT(m2.cont_date, "%Y%m") AS Month, SUM(COALESCE(s.Amount, 0)) AS Amount
from (
select (select MAX(`Date`) from sales) - interval (year.b * 10 + month.a) MONTH AS cont_date
from (
select 0 b union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) AS year
CROSS JOIN
(
select 0 a union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) AS month
where (year.b * 10 + month.a) < (select timestampdiff(month, MIN(`Date`), MAX(`Date`)) + 1 from sales) ) m2
LEFT JOIN sales s ON s.Customer = "paul" AND DATE_FORMAT(m2.cont_date, "%Y%m") = DATE_FORMAT(s.`Date`, "%Y%m")
GROUP BY Month;
Salida:
mysql> select * from sales;
+----------+------------+--------+
| Customer | Date | Amount |
+----------+------------+--------+
| Paul | 2015-01-15 | 2000 |
| Jonathan | 2015-01-15 | 3000 |
| Taylor | 2015-01-15 | 2000 |
| Mark | 2015-01-15 | 3000 |
| Paul | 2015-02-15 | 2000 |
| Jonathan | 2015-02-15 | 3000 |
| Paul | 2015-02-25 | 4000 |
| Jonathan | 2015-02-25 | 5000 |
| Jonathan | 2015-03-15 | 2000 |
| Jonathan | 2015-04-15 | 5000 |
| Taylor | 2015-04-25 | 4000 |
| Mark | 2015-04-25 | 5000 |
| Paul | 2015-05-25 | 4000 |
| Jonathan | 2015-05-25 | 5000 |
| Taylor | 2015-05-25 | 4000 |
| Mark | 2015-05-25 | 5000 |
+----------+------------+--------+
16 rows in set (0.00 sec)
mysql>
mysql> -- query wanted
mysql> select
-> COALESCE(s.Customer, "") AS Customer, DATE_FORMAT(m2.cont_date, "%Y%m") AS Month, SUM(COALESCE(s.Amount, 0)) AS Amount
-> from (
-> select (select MAX(`Date`) from sales) - interval (year.b * 10 + month.a) MONTH AS cont_date
-> from (
-> select 0 b union select 1 union select 2 union select 3 union select 4 union
-> select 5 union select 6 union select 7 union select 8 union select 9) AS year
-> CROSS JOIN
-> (
-> select 0 a union select 1 union select 2 union select 3 union select 4 union
-> select 5 union select 6 union select 7 union select 8 union select 9) AS month
-> where (year.b * 10 + month.a) < (select timestampdiff(month, MIN(`Date`), MAX(`Date`)) + 1 from sales) ) m2
-> LEFT JOIN sales s ON s.Customer = "paul" AND DATE_FORMAT(m2.cont_date, "%Y%m") = DATE_FORMAT(s.`Date`, "%Y%m")
-> GROUP BY Month;
+----------+--------+--------+
| Customer | Month | Amount |
+----------+--------+--------+
| Paul | 201501 | 2000 |
| Paul | 201502 | 6000 |
| | 201503 | 0 |
| | 201504 | 0 |
| Paul | 201505 | 4000 |
+----------+--------+--------+
5 rows in set (0.00 sec)
0 para la respuesta № 2
Puedes crear una tabla en línea, con todos los meses, y luego unirte a tu tabla de ventas.
Algo como esto:
SELECT s.customer_name as Customer,
CONCAT(months.m, "-", years.y) as Month,
s.amount as Amount
FROM (
SELECT "01" AS m UNION ALL SELECT "02" UNION ALL SELECT "03" UNION ALL
SELECT "04" UNION ALL SELECT "05" UNION ALL SELECT "06" UNION ALL
SELECT "07" UNION ALL SELECT "08" UNION ALL SELECT "09" UNION ALL
SELECT "10" UNION ALL SELECT "11" UNION ALL SELECT "12") AS months
CROSS JOIN (
SELECT "2015" AS y UNION ALL SELECT "2016") AS years
LEFT JOIN sales_table AS s
ON DATE_FORMAT(s.date, "%Y-%c") = CONCAT(years.y, "-", months.m)
GROUP BY CONCAT(months.m, "-", years.y)