简体   繁体   English

SQL 查询计算并显示过去12个月每个月的总和数据

[英]SQL query calculate and display sum data per each of the past 12 months

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.对于高级 sql 查询,我是新手。 I have tried following some examples on SO but still haven't got it yet.我已经尝试在 SO 上遵循一些示例,但仍然没有得到它。

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.我想要做的是确保当我显示图表时,它将显示过去 12 个月的分数和那些月份没有分数的零值。

#Edit 3 The table below is just a visualisation of what i want to achieve. #Edit 3 下表只是我想要实现的目标的可视化。 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.正如您在分数表中注意到的那样,一天有 2 个分数条目。 In my totals i would like for those scores to all be computed for the month of October.在我的总数中,我希望这些分数全部计算在 10 月份。

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;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.我回声看看$query_result是否会给我一个数组,这样我就可以通过在 Chart.js 数据值脚本中执行get_last_12_month_scores()[i]来捕获数组中的各个值。 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.正是在这一点上,我意识到我要么不知道自己在做什么,要么不得不寻求帮助以避免浪费时间。

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)

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.我的解决方案不会为空月份添加值,这可以在您的 php 中呈现 output 时处理,但会区分年份。 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 特定年份你可以这样做:

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在这里小提琴: 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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM