91

I have a table of student scorecard. here is the table,

subject  | mark1 | mark2 | mark3 |......|markn
stud1    | 99    | 87    | 92    |      | 46
stud2    |....................................
  .
  .
studn    |....................................|

Now, I need to sum it for each student of total marks. I got it by using sum(mark1+mark2+...+markn) group by stud. I want to know how to sum it without adding each column name,it will be huge when in case up to marks26. so could anyone know how to fix it.

starball
  • 20,030
  • 7
  • 43
  • 238
rk3265423
  • 947
  • 1
  • 6
  • 7

8 Answers8

125
SELECT student, (SUM(mark1)+SUM(mark2)+SUM(mark3)....+SUM(markn)) AS Total
 FROM your_table
 GROUP BY student
Maulik patel
  • 2,546
  • 2
  • 20
  • 26
  • 6
    `I want to know how to sum it without adding each column name` quoted. – majidarif Mar 13 '14 at 05:10
  • 7
    @Maulik patel, Instead of that (sum(mark1)+sum(mark2)....+sum(markn)), It's better to follow sum(mark1+mark2+...+markn). – rk3265423 Mar 13 '14 at 10:34
  • 1
    this could be useful when handling NULL fields http://stackoverflow.com/questions/7602271/how-do-i-get-sum-function-in-mysql-to-return-0-if-no-values-are-found – Rashi Nov 19 '14 at 13:03
  • 1
    Yes use when fields is null – Maulik patel Nov 19 '14 at 13:07
  • I agree with @Rashi - using `COALESCE` is a good pattern. But I wonder why the `+` operator doesn't ignore NULL values by default, like `SUM` does... – flow2k Jun 21 '20 at 10:56
33

Another way of doing this is by generating the select query. Play with this fiddle.

SELECT CONCAT('SELECT ', group_concat(`COLUMN_NAME` SEPARATOR '+'), ' FROM scorecard') 
FROM  `INFORMATION_SCHEMA`.`COLUMNS` 
WHERE `TABLE_SCHEMA` = (select database()) 
AND   `TABLE_NAME`   = 'scorecard'
AND   `COLUMN_NAME` LIKE 'mark%';

The query above will generate another query that will do the selecting for you.

  1. Run the above query.
  2. Get the result and run that resulting query.

Sample result:

SELECT mark1+mark2+mark3 FROM scorecard

You won't have to manually add all the columns anymore.

majidarif
  • 18,694
  • 16
  • 88
  • 133
  • This above query will be more helpful to retrieve the column names which are required from huge column names. But it needs additional query to sum up the values from the first query. If, it is simple and single it could be better for every one who are looking like this and thanks anyway. – rk3265423 Mar 13 '14 at 10:16
22

If any of your markn columns are "AllowNull" then you will need to do a little extra to insure the correct result is returned, this is because 1 NULL value will result in a NULL total.

This is what i would consider to be the correct answer.

SUM(IFNULL(`mark1`, 0) + IFNULL(`mark2`, 0) + IFNULL(`mark3`, 0)) AS `total_marks` 

IFNULL will return the 2nd parameter if the 1st is NULL. COALESCE could be used but i prefer to only use it if it is required. See What is the difference bewteen ifnull and coalesce in mysql?

SUM-ing the entire calculation is tidier than SUM-ing each column individually.

SELECT `student`, SUM(IFNULL(`mark1`, 0) + IFNULL(`mark2`, 0) + IFNULL(`mark3`, 0)) AS `total_marks` 
FROM student_scorecard
GROUP BY `student`

i want to know how to sum it without adding each column name,it will be huge when in case up to marks26

To generate and execute this statement dynamically in sql you would need to use the INFORMATION_SCHEMA.COLUMNS table to create a query string then execute it using a prepared statement saved in a variable.

SELECT CONCAT('SELECT `student`, SUM(IFNULL(`', group_concat(`COLUMN_NAME` SEPARATOR '`, 0) + IFNULL(`'), '`, 0) AS `total_marks` FROM `student_scorecard` GROUP BY `student`') 
FROM `INFORMATION_SCHEMA`.`COLUMNS` 
WHERE `TABLE_SCHEMA` = (select DATABASE()) 
AND `TABLE_NAME`   = 'student_scorecard'
AND `COLUMN_NAME` LIKE 'mark%'
# adapted from https://stackoverflow.com/a/22369767/2273611


# insert statement sql into a variable
INTO @statement_var;

#prepare the statement string
PREPARE stmt_name FROM @statement_var;

#execute the prepared statement/query
EXECUTE stmt_name;

# release statement
DEALLOCATE PREPARE stmt_name;
TarranJones
  • 4,084
  • 2
  • 38
  • 55
  • Just a quick note, if you follow this and try it out in PHPMYADMIN, it will predict an error, but still work. Just hit the `GO` button. – Sablefoste Nov 18 '21 at 16:05
9

SELECT student, SUM(mark1+mark2+mark3+....+markn) AS Total FROM your_table

Harat
  • 1,340
  • 1
  • 17
  • 20
6

The short answer is there's no great way to do this given the design you have. Here's a related question on the topic: Sum values of a single row?

If you normalized your schema and created a separate table called "Marks" which had a subject_id and a mark column this would allow you to take advantage of the SUM function as intended by a relational model.

Then your query would be

SELECT subject, SUM(mark) total 
FROM Subjects s 
  INNER JOIN Marks m ON m.subject_id = s.id
GROUP BY s.id
Community
  • 1
  • 1
Jon Todd
  • 111
  • 2
  • If it is normalized schema,then i think it would be better to follow the way which you explained above. But it's not possible in all cases. Everything are not normalized according to me and no need to normalize for run-time requirement.If i am wrong sorry me.Thanks @Jon Todd. – rk3265423 Mar 13 '14 at 10:24
4

//Mysql sum of multiple rows Hi Here is the simple way to do sum of columns

SELECT sum(IF(day_1 = 1,1,0)+IF(day_3 = 1,1,0)++IF(day_4 = 1,1,0)) from attendence WHERE class_period_id='1' and student_id='1'
Ambarish
  • 139
  • 1
  • 5
1

You could change the database structure such that all subject rows become a column variable (like spreadsheet). This makes such analysis much easier

corwa
  • 21
  • 1
  • 4
    Welcome to Stack Overflow, please [take the tour](https://stackoverflow.com/tour), make sure you read [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) and update your answer with more information. – lordrhodos Jun 15 '17 at 07:38
0

select ((max(assignment1))+(max(assignment2))+(max(assignment3))-(min(assignment1))+(min(assignment2))+(min(assignment3)))from box_scores;

priya
  • 1