Attempting to create a ‘Previous Year’ vs ‘Current Year’ Graph using a jQuery plug-in with data from my MySQL database.
The data for such is like this
var previousyear = [ [1, 24monthsago], [2, 23monthsago], [3, 22monthsago], [4, 21monthsago], [5, 20monthsago], [6, 19monthsago], [7, 18monthsago], [8, 17monthsago], [9, 16monthsago], [10, 15monthsago], [11, 14monthsago], [12, 13monthsago] ]; var currentyear = [ [1, 12monthsago], [2, 11monthsago], [3, 10monthsago], [4, 9monthsago], [5, 8monthsago], [6, 7monthsago], [7, 6monthsago], [8, 5monthsago], [9, 4monthsago], [10, 3monthsago], [11, 2monthsago], [12, 1monthago] ];
if we pretend the xmonthsago
is an integer value.
The case I am working for is a database for an Inventory System and I am looking to create a 24-month span for sold counts on certain SKUs using my inventory_history
table.
I have used this current query with success:
SELECT Date_format(lastmodified, '%Y') AS 'year', Date_format(lastmodified, '%m') AS 'month', Count(id) AS 'total' FROM inventory_history WHERE inventory_history.sku = 'SKU_NAME' GROUP BY Date_format(lastmodified, '%Y%m');
Which, for example, outputs:
╔══════╦═══════╦═══════╗ ║ year ║ month ║ total ║ ╠══════╬═══════╬═══════╣ ║ 2017 ║ 08 ║ 2 ║ ║ 2017 ║ 12 ║ 1 ║ ║ 2018 ║ 01 ║ 1 ║ ║ 2018 ║ 03 ║ 1 ║ ║ 2019 ║ 02 ║ 1 ║ ╚══════╩═══════╩═══════╝
I am wondering if it is possible to streamline this query even more to give me a proper output which includes all months in between that do not have any COUNT
s
Output something like this:
╔══════╦═══════╦═══════╗ ║ year ║ month ║ total ║ ╠══════╬═══════╬═══════╣ ║ 2017 ║ 08 ║ 2 ║ ║ 2017 ║ 09 ║ 0 ║ ║ 2017 ║ 10 ║ 0 ║ ║ 2017 ║ 11 ║ 0 ║ ║ 2017 ║ 12 ║ 1 ║ ║ 2018 ║ 01 ║ 1 ║ ║ 2018 ║ 02 ║ 0 ║ ║ 2018 ║ 03 ║ 1 ║ ║ 2018 ║ 04 ║ 0 ║ ║ 2018 ║ 05 ║ 0 ║ ║ 2018 ║ 06 ║ 0 ║ ║ 2018 ║ 07 ║ 0 ║ ║ 2018 ║ 08 ║ 0 ║ ║ 2018 ║ 09 ║ 0 ║ ║ 2018 ║ 10 ║ 0 ║ ║ 2018 ║ 11 ║ 0 ║ ║ 2018 ║ 12 ║ 0 ║ ║ 2019 ║ 01 ║ 0 ║ ║ 2019 ║ 02 ║ 1 ║ ║ 2019 ║ 03 ║ 0 ║ ║ 2019 ║ 04 ║ 0 ║ ║ 2019 ║ 05 ║ 0 ║ ║ 2019 ║ 06 ║ 0 ║ ║ 2019 ║ 07 ║ 0 ║ ║ 2019 ║ 08 ║ 0 ║ ╚══════╩═══════╩═══════╝
Anyone have any idea on how I may accomplish this with a MySQL query?
Advertisement
Answer
If you have data in the table for all months, the simplest method is probably conditional aggregation:
SELECT year(lastmodified) AS year, month(lastmodified) AS month, SUM(ih.sku = 'SKU_NAME') AS total FROM inventory_history ih GROUP BY year, month;
Notes:
- There is no reason to use
date_format()
when MySQL has convenient built-in functions. - Only use single quotes for string and date constants, not for column aliases especially.
- You don’t need to escape your column aliases.
- The
GROUP BY
columns should match the unaggregated columns in theSELECT
. They can use aliases. - The
SUM()
uses a very convenient feature of MySQL. It treats booleans as integers, with 1 for true and 0 for false.