-2

I am trying to create a chart where by i will display data from my scores table and that data must be per the total scores from each month. I am a novice when it comes to advanced sql queries. I have tried following some examples on SO but still haven't got it yet.

Below is the scores table

---------------------------------
id     | marks  | date_created   
---------------------------------
1      |   100  |  2020-03-12
2      |   90   |  2020-08-25
3      |   100  |  2021-04-10
4      |   95   |  2021-06-20
5      |   99   |  2021-10-02
6      |   97   |  2021-10-02

What i want to do is make sure that when i display the chart, it will show scores from the past 12 months and zeros where those months don't have scores.

#Edit 3 The table below is just a visualisation of what i want to achieve. I dont have it yet in the database. I only have the scores table

---------------------------------
month        |   sum(marks)
---------------------------------
October      |   0
September    |   0
August       |   0
July         |   0
June         |   95
May          |   0
April        |   100
March        |   100
February     |   0
January      |   0
December     |   0
November     |   0

As you can notice in the table, i want the latest month to be what's sorted last How can i achieve this? Thanks

Edit #1

The marks from the different scores are summations of marks from total days in individual months. As you can notice on the scores table, there's a day with 2 score entries. In my totals i would like for those scores to all be computed for the month of October.

Edit #2


function get_last_12_month_scores(){
    $db = Database::getInstance();
    $mysqli = $db->getConnection();
    $user_id = $_SESSION['user_id'];

    $query_count = "SELECT SUM(`marks`) as `total` FROM `scores` WHERE `user_id`='$user_id';

    $month_12_query_count =
        "SELECT
            SUM(IF(month = 'Jan', total, 0)) as 'Jan',
            SUM(IF(month = 'Feb', total, 0)) as 'Feb',
            SUM(IF(month = 'Mar', total, 0)) as 'Mar',
            SUM(IF(month = 'Apr', total, 0)) as 'Apr',
            SUM(IF(month = 'May', total, 0)) as 'May',
            SUM(IF(month = 'Jun', total, 0)) as 'Jun',
            SUM(IF(month = 'Jul', total, 0)) as 'Jul',
            SUM(IF(month = 'Aug', total, 0)) as 'Aug',
            SUM(IF(month = 'Sep', total, 0)) as 'Sep',
            SUM(IF(month = 'Oct', total, 0)) as 'Oct',
            SUM(IF(month = 'Nov', total, 0)) as 'Nov',
            SUM(IF(month = 'Dec', total, 0)) as 'Dec',
            SUM(total) as total_yearly
        FROM (
            SELECT DATE_FORMAT(date_added, '%b') as month, SUM($query_count as total
            FROM scores
            WHERE date_added <= now() and date >= Date_add(now(),interval - 12 month)
            GROUP BY DATE_FORMAT(date_added, '%m-%Y'))) as sub";

    $query_result = $mysqli->query($month_12_query_count);

    echo $query_result;
}

With echo $query_result; i echoed to see if $query_result would give me an array such that i could be able to capture the individual values in the array by doing get_last_12_month_scores()[i] in the Chart.js data values script. But it unfortunately didn't

It's at this that i realised i was either not aware what i was doing or had to just seek help to avoid wasting time.

NMukama
  • 1,114
  • 9
  • 10
  • Pls share what you have tried and where you got stuck! – Shadow Oct 05 '21 at 11:04
  • Let me edit my question on Edit #2 and show what i'm having right now. Which is really an attempt to follow solutions from allover the internet – NMukama Oct 05 '21 at 11:10
  • Does 2nd table completely matches source data from 1st table? why the values for src rows 2,5,6 are not used? – Akina Oct 05 '21 at 11:18
  • Those are not being used because they dont fit in the range of the past 12 months in this case counting from today OCtober 2021 – NMukama Oct 05 '21 at 11:22
  • You do not need to pivot the resultset (no need for conditional counting). Just sum totals per month using the group by clause in your inner query, then follow the accepted answer in this SO question: https://stackoverflow.com/questions/34557199/mysql-count-by-month-including-missing-records – Shadow Oct 05 '21 at 11:31
  • that group_by clause is unfortunately the one raising issues. I am unable to return an array of elements in the table. Because what i had wanted is that i return summations of all entries from a particular month and then use the 12 rows to pupulate my graph. As things stand now, the only result i get is a boolean on the select statement. Even $mysqli->query($result) doesnot work – NMukama Oct 05 '21 at 13:13

2 Answers2

0

Here is a track :

SELECT
 sum(case when month(date_created) = 10 then marks else 0 end) October,
 sum(case when month(date_created) = 9 then marks else 0 end) September,
 sum(case when month(date_created) = 8 then marks else 0 end) August,
 sum(case when month(date_created) = 7 then marks else 0 end) July,
 sum(case when month(date_created) = 6 then marks else 0 end) June,
 sum(case when month(date_created) = 5 then marks else 0 end) May,
 sum(case when month(date_created) = 4 then marks else 0 end) April,
 sum(case when month(date_created) = 3 then marks else 0 end) March,
 sum(case when month(date_created) = 2 then marks else 0 end) February,
 sum(case when month(date_created) = 1 then marks else 0 end) January,
 sum(case when month(date_created) = 12 then marks else 0 end) December,
 sum(case when month(date_created) = 11 then marks else 0 end) November
FROM scores 
GROUP BY month(date_created)
Atika
  • 1,025
  • 2
  • 6
  • 17
  • What if you have data from multiple years? – Shadow Oct 05 '21 at 11:25
  • @Atika table 2 is just a visualisation of what i intend on achieving logically. That way it can become simpler to plot. The only table i have in the database is the scores table – NMukama Oct 05 '21 at 11:28
0

My solution does not add a value for empty months, which could be dealt with when rendering the output in your php, but does differentiates between years. Otherwise, to get the missing months you could create an extra table to cross reference, see this thread:

SELECT YEAR(date_created), MONTH(date_created), sum( mark )
FROM scores
GROUP BY YEAR(date_created), MONTH(date_created)

Or to select a specific year you can do:

SELECT MONTH(date_created), sum(mark)
FROM scores
WHERE YEAR(date_created) = 2020 -- target year
GROUP BY MONTH(date_created)

Fiddle here: http://sqlfiddle.com/#!9/f5f62e/1

-- create a table
CREATE TABLE scores (
  id INTEGER PRIMARY KEY,
  mark INTEGER NOT NULL,
  date_created date NOT NULL
);

-- insert some values
INSERT INTO scores VALUES (1, '100', '2020-03-12');
INSERT INTO scores VALUES (2, '90', '2020-08-25');
INSERT INTO scores VALUES (3, '100', '2021-04-10');
INSERT INTO scores VALUES (4, '95', '2021-06-20');
INSERT INTO scores VALUES (5, '99', '2021-10-02');
INSERT INTO scores VALUES (6, '99', '2021-10-05');
WPhil
  • 1,056
  • 1
  • 7
  • 12