Reputation: 309
I am trying to generate total monthly sales for 2021 based on the procedure name by month. Each row must contain procedure name and months names and if any month has any sale, the total of the sale must be output otherwise zero. so far I managed what I am looking for displaying the procedure names and months, however the months with sales showing the total sales of the year,
SELECT
tt.procedure_name,
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'January', 1, 0)) AS 'January',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'February', 1, 0)) AS 'February',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'March', 1, 0)) AS 'March',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'April', 1, 0)) AS 'April',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'May', 1, 0)) AS 'May',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'June', 1, 0)) AS 'June',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'July', 1, 0)) AS 'July',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'August', 1, 0)) AS 'August',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'September', 1, 0)) AS 'September',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'October', 1, 0)) AS 'October',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'November', 1, 0)) AS 'November',
SUM(IF(DATE_FORMAT(mt.plan_date, '%M') = 'December', 1, 0)) AS 'December'
FROM
treatments tt
LEFT JOIN (
SELECT
plan_date,procedure_name
FROM
treatments
WHERE
YEAR(plan_date) = 2021
GROUP BY
DATE_FORMAT(plan_date, '%M'),procedure_name
ORDER BY
plan_date ASC,
procedure_name ASC
) mt ON mt.procedure_name = tt.procedure_name
WHERE
YEAR(tt.plan_date) = 2021
GROUP BY
tt.procedure_name
ORDER BY
tt.procedure_name ASC
Wrong Table:
|procedure_name|January|February|March|April|May|June|July|August|September|October|November|December|
|--------------|-------|--------|-----|-----|---|----|----|------|---------|-------|--------|--------|
|Botox |5 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |5 |
|Fillers |2 |0 |2 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
Correct table should be:
|procedure_name|January|February|March|April|May|June|July|August|September|October|November|December|
|--------------|-------|--------|-----|-----|---|----|----|------|---------|-------|--------|--------|
|Botox |2 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |3 |
|Fillers |1 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
Upvotes: 0
Views: 61
Reputation: 94894
Why the self outer join? I suppose you simply want:
SELECT
tt.procedure_name,
SUM(MONTH(tt.plan_date) = 1) AS "January",
SUM(MONTH(tt.plan_date) = 2) AS "February",
SUM(MONTH(tt.plan_date) = 3) AS "March",
SUM(MONTH(tt.plan_date) = 4) AS "April",
SUM(MONTH(tt.plan_date) = 5) AS "May",
SUM(MONTH(tt.plan_date) = 6) AS "June",
SUM(MONTH(tt.plan_date) = 7) AS "July",
SUM(MONTH(tt.plan_date) = 8) AS "August",
SUM(MONTH(tt.plan_date) = 9) AS "September",
SUM(MONTH(tt.plan_date) = 10) AS "October",
SUM(MONTH(tt.plan_date) = 11) AS "November",
SUM(MONTH(tt.plan_date) = 12) AS "December"
FROM
treatments tt
WHERE
YEAR(tt.plan_date) = 2021
GROUP BY
tt.procedure_name
ORDER BY
tt.procedure_name ASC;
If you want to include treatments that have no sale in any month in 2021:
SELECT
p.procedure_name,
SUM(MONTH(tt.plan_date) = 1) AS "January",
SUM(MONTH(tt.plan_date) = 2) AS "February",
SUM(MONTH(tt.plan_date) = 3) AS "March",
SUM(MONTH(tt.plan_date) = 4) AS "April",
SUM(MONTH(tt.plan_date) = 5) AS "May",
SUM(MONTH(tt.plan_date) = 6) AS "June",
SUM(MONTH(tt.plan_date) = 7) AS "July",
SUM(MONTH(tt.plan_date) = 8) AS "August",
SUM(MONTH(tt.plan_date) = 9) AS "September",
SUM(MONTH(tt.plan_date) = 10) AS "October",
SUM(MONTH(tt.plan_date) = 11) AS "November",
SUM(MONTH(tt.plan_date) = 12) AS "December"
FROM
(SELECT DISTINCT procedure_name FROM treatments) p
LEFT OUTER JOIN
treatments tt
ON tt.procedure_name = p.procedure_name
AND YEAR(tt.plan_date) = 2021
GROUP BY
p.procedure_name
ORDER BY
p.procedure_name ASC;
Update: You say you have a procedures table. In that case I suggest you use this and join the aggregated data:
SELECT *
FROM procedure p
LEFT JOIN
(
SELECT
procedure_name,
SUM(MONTH(plan_date) = 1) AS "January",
SUM(MONTH(plan_date) = 2) AS "February",
SUM(MONTH(plan_date) = 3) AS "March",
SUM(MONTH(plan_date) = 4) AS "April",
SUM(MONTH(plan_date) = 5) AS "May",
SUM(MONTH(plan_date) = 6) AS "June",
SUM(MONTH(plan_date) = 7) AS "July",
SUM(MONTH(plan_date) = 8) AS "August",
SUM(MONTH(plan_date) = 9) AS "September",
SUM(MONTH(plan_date) = 10) AS "October",
SUM(MONTH(plan_date) = 11) AS "November",
SUM(MONTH(plan_date) = 12) AS "December"
FROM treatments
WHERE YEAR(plan_date) = 2021
GROUP BY procedure_name
) t ON t.procedure_name = p.procedure_name
ORDER BY p.procedure_name;
Upvotes: 1