MySQL MAX(): Find the Highest Value in a Column

MySQL MAX() returns the highest non-NULL value produced by an expression. It can be used with numbers, dates, and text values.

SELECT MAX(mark) AS max_mark
FROM student;

For the sample rows below, the highest mark is 85.

MAX() returns the maximum value, not automatically the complete row that contains it. If you also need the student's id, name, class, or other columns, use a subquery, JOIN, or window function as shown below.
MySQL MAX query example

MAX() Syntax Top ↑

SELECT MAX(expression)
FROM table_name;

MAX() ignores NULL values. If no non-NULL value is available, the aggregate result is NULL.

Basic MAX() Example Top ↑

The first examples use these rows from the student table:

idnameclassmark
1John DeoFour75
2Max RuinThree85
3ArnoldThree55
4Krish StarFour60
5John MikeFour60
6Alex JohnFour55
SELECT MAX(mark) AS max_mark
FROM student;
max_mark
85

The alias max_mark gives the aggregate result a useful column name.

Get the Complete Row with the Maximum Value Top ↑

This is a common requirement: find the highest mark and also return the student who has that mark.

Do not write:

-- Wrong or invalid for this purpose
SELECT id,
       name,
       class,
       MAX(mark) AS max_mark
FROM student;

With ONLY_FULL_GROUP_BY enabled, MySQL rejects this because the non-aggregate columns are not grouped. With permissive settings, those columns can come from an arbitrary row and are not guaranteed to belong to the maximum mark.

Use a subquery instead:

SELECT id,
       name,
       class,
       mark
FROM student
WHERE mark = (
    SELECT MAX(mark)
    FROM student
);

This returns every student whose mark equals the maximum value.

Return one row only Top ↑

If the requirement is specifically to return only one highest row, sort and limit the result:

SELECT id,
       name,
       class,
       mark
FROM student
ORDER BY mark DESC, id
LIMIT 1;

The secondary id sort provides deterministic tie-breaking. See top and second-highest value examples.

What Happens When Several Rows Share the Maximum? Top ↑

A subquery using WHERE mark = (SELECT MAX(mark) ...) returns all ties.

For example, if two students both have mark 96:

SELECT id,
       name,
       mark
FROM student
WHERE mark = (
    SELECT MAX(mark)
    FROM student
)
ORDER BY id;

Both rows are returned. This is usually preferable when "all students with the highest mark" is the real requirement.

Maximum Value in Each Group Top ↑

Use GROUP BY to calculate the maximum for each class:

SELECT class,
       MAX(mark) AS max_mark
FROM student
GROUP BY class
ORDER BY class;
classmax_mark
Four75
Three85

This query returns the maximum mark for each group, but it still does not identify the full student row that produced each maximum.

Complete Row with the Maximum in Each Group Top ↑

To return the student rows that contain each class maximum, first calculate the maximum for each class and then join those results back to the source table:

SELECT s.id,
       s.name,
       s.class,
       s.mark
FROM student AS s
JOIN (
    SELECT class,
           MAX(mark) AS max_mark
    FROM student
    GROUP BY class
) AS m
  ON m.class = s.class
 AND m.max_mark = s.mark
ORDER BY s.class, s.id;

This correctly returns ties as separate rows when two students share the highest mark in the same class.

MySQL 8.0 window-function alternative Top ↑

With MySQL 8.0+, RANK() provides another clear solution:

WITH ranked AS (
    SELECT id,
           name,
           class,
           mark,
           RANK() OVER (
               PARTITION BY class
               ORDER BY mark DESC
           ) AS rnk
    FROM student
)
SELECT id,
       name,
       class,
       mark
FROM ranked
WHERE rnk = 1
ORDER BY class, id;

RANK() keeps tied highest rows. Use ROW_NUMBER() instead only when the requirement is exactly one row per group and you have defined a deliberate tie-breaker.

MAX() with WHERE Top ↑

A WHERE clause filters the rows before MAX() is calculated.

SELECT MAX(mark) AS max_mark
FROM student
WHERE class = 'Four';

For the sample table, the maximum mark in class Four is 75.

If you select class as well, group by it:

SELECT class,
       MAX(mark) AS max_mark
FROM student
WHERE class = 'Four'
GROUP BY class;

MAX() with JOIN Top ↑

When data comes from related tables, aggregate only the columns that belong to the grouping logic. Do not select an unrelated product column beside MAX(qty) unless the query also identifies which row produced that maximum.

For example, find the maximum quantity recorded for each store:

SELECT a.store,
       MAX(a.qty) AS max_qty
FROM sales AS a
GROUP BY a.store
ORDER BY a.store;

If you then need the matching product row and its price, calculate the maximum by store first and join back to sales, followed by the product table:

SELECT s.store,
       s.qty AS max_qty,
       p.product,
       p.price,
       p.price * s.qty AS total_price
FROM sales AS s
JOIN (
    SELECT store,
           MAX(qty) AS max_qty
    FROM sales
    GROUP BY store
) AS m
  ON m.store = s.store
 AND m.max_qty = s.qty
LEFT JOIN products AS p
  ON p.p_id = s.p_id
ORDER BY s.store, s.p_id;

This avoids the old pattern of grouping only by store while selecting a product that is not functionally tied to the aggregate result.

Products and sales JOIN example

MAX() as a Window Function Top ↑

GROUP BY collapses multiple source rows into one result row per group. A window-function form of MAX() keeps each detail row while adding the group maximum beside it:

SELECT id,
       name,
       class,
       mark,
       MAX(mark) OVER (
           PARTITION BY class
       ) AS class_max
FROM student
ORDER BY class, id;

This is useful for reports that need both the original row and the class maximum. See the existing OVER() and PARTITION BY tutorial.

MAX() on Text Values Top ↑

MAX() can also operate on character columns. MySQL compares text according to the column's collation.

SELECT MAX(name) AS max_name
FROM student;

This returns the greatest text value according to the active collation. It is not a numeric comparison and should not be described simply as "the highest alphabet."

Numbers Stored in VARCHAR Top ↑

If numbers are stored as text, MAX() compares the text representation rather than the numeric value.

For these VARCHAR values:

'1', '2', '3', '4', '5', '6', '12', '13'

a text comparison can produce 6 as the maximum because the values are compared lexically.

Convert the values to a numeric type before taking the maximum:

SELECT MAX(
           CONVERT(t1, UNSIGNED)
       ) AS numeric_max
FROM max_value;

The result is 13.

Sample table:

CREATE TABLE max_value (
    t1 VARCHAR(2) NOT NULL
) ENGINE=InnoDB
  DEFAULT CHARSET=utf8mb4;

INSERT INTO max_value
    (t1)
VALUES
    ('1'),
    ('2'),
    ('3'),
    ('4'),
    ('5'),
    ('6'),
    ('12'),
    ('13');
If a column represents numbers, storing them in an appropriate numeric datatype is normally better than repeatedly converting text during queries.

See MySQL CONVERT() for more conversion examples.

MAX() on DATE and DATETIME Top ↑

On a DATE or DATETIME column, MAX() returns the latest non-NULL date/time value.

SELECT MAX(exam_dt) AS latest_exam
FROM student_mark;

Latest exam date for each month Top ↑

When the table can contain more than one year, grouping only by month number mixes January from different years. Group by both year and month:

SELECT YEAR(exam_dt) AS exam_year,
       MONTH(exam_dt) AS exam_month,
       MAX(exam_dt) AS latest_exam
FROM student_mark
GROUP BY YEAR(exam_dt),
         MONTH(exam_dt)
ORDER BY exam_year, exam_month;

Download the existing student_mark sample SQL data.

NULL Values and MAX() Top ↑

MAX() ignores NULL values. If every selected value is NULL, or no rows satisfy the filter, the result is NULL.

SELECT MAX(mark) AS max_mark
FROM student
WHERE id > 1000;

If the application needs a fallback value, use COALESCE() only when that fallback has a correct business meaning:

SELECT COALESCE(
           MAX(mark),
           0
       ) AS max_mark
FROM student
WHERE id > 1000;

Store Maximum Rows in Another Table Top ↑

You can create a new table containing the row or rows with the maximum mark:

CREATE TABLE student_max AS
SELECT id,
       name,
       class,
       mark
FROM student
WHERE mark = (
    SELECT MAX(mark)
    FROM student
);
CREATE TABLE ... AS SELECT copies the selected data and derives column definitions, but it does not reproduce all indexes, constraints, AUTO_INCREMENT properties, triggers, or other table attributes from the source table.

If you need a new table with the source table's structure first, use:

CREATE TABLE student_max
LIKE student;

INSERT INTO student_max
    (id, name, class, mark)
SELECT id,
       name,
       class,
       mark
FROM student
WHERE mark = (
    SELECT MAX(mark)
    FROM student
);

If the destination table already exists, use an INSERT ... SELECT approach.

Using MAX() in a PHP PDO Script Top ↑

After connecting to MySQL with PDO, a static grouped MAX query can be executed with query():

<?php
$sql="SELECT class,
             MAX(mark) AS max_mark
      FROM student
      GROUP BY class
      ORDER BY class";

$stmt=$dbo->query($sql);

foreach($stmt as $row){
    echo '<p>'
        .htmlspecialchars(
            $row['class'],
            ENT_QUOTES,
            'Windows-1252'
        )
        .' : '
        .htmlspecialchars(
            (string)$row['max_mark'],
            ENT_QUOTES,
            'Windows-1252'
        )
        .'</p>';
}

This query contains no external values, so query() is appropriate. When the class or another condition comes from user input, use a prepared statement and bind the value.

Performance Notes Top ↑

  • A simple MAX(indexed_column) query can often benefit from an appropriate index, depending on the filter, table structure, and optimizer plan.
  • If the query filters first, indexes that support the WHERE condition can matter as much as the MAX expression.
  • Grouping by functions such as YEAR(date_col) and MONTH(date_col) can require more work than grouping by a stored/indexed reporting key on very large tables.
  • Converting a VARCHAR column to a number during every query adds work. Use a numeric datatype when the data is fundamentally numeric.
  • Use EXPLAIN and real query measurements for performance decisions rather than assuming every MAX query requires a special optimization.

Common MAX() Mistakes Top ↑

Selecting unrelated columns beside MAX() Top ↑

SELECT name, MAX(mark) FROM student does not reliably return the name belonging to the highest mark. Use a subquery, JOIN, or window function.

Forgetting about ties Top ↑

A maximum value can belong to more than one row. Decide whether the requirement is to return every tied row or exactly one row with an explicit tie-breaker.

Grouping only by month number across several years Top ↑

GROUP BY MONTH(exam_dt) combines the same month from different years. Include the year when the data spans multiple years.

Using MAX() on numeric values stored as text Top ↑

VARCHAR values are compared as text. Store numeric data in a numeric datatype whenever practical.

Assuming CREATE TABLE ... AS SELECT copies the complete schema Top ↑

It does not preserve all indexes, constraints, AUTO_INCREMENT properties, triggers, and other source-table attributes.

Using MAX(id) to find the row your application just inserted Top ↑

Do not use MAX(id) as an insert-ID mechanism. Another connection may insert a newer row. Use LAST_INSERT_ID() or the database API's insert-ID feature.

Video: SQL MAX and the Complete Highest-value Row Top ↑

Download the full Plus2net student table SQL dump

Frequently Asked Questions Top ↑

Q1: What does MAX() return in MySQL?

MAX() returns the highest non-NULL value produced by the selected expression.

Q2: How do I get the complete row containing the maximum value?

Compare the column with a subquery such as WHERE mark = (SELECT MAX(mark) FROM student), or use a JOIN or window function.

Q3: What happens if two rows have the same maximum value?

A subquery that compares the column with MAX() returns all matching ties. ORDER BY with LIMIT 1 returns only one row according to the specified tie-breaker.

Q4: How do I find the maximum value for each group?

Use MAX() with GROUP BY, for example SELECT class, MAX(mark) FROM student GROUP BY class.

Q5: Does MAX() ignore NULL values?

Yes. NULL values are ignored. If there is no non-NULL value to evaluate, the result is NULL.

Q6: Can MAX() be used with dates?

Yes. On DATE or DATETIME values, MAX() returns the latest non-NULL date or time.

Q7: Why can MAX() give an unexpected result for numbers stored in VARCHAR?

VARCHAR values are compared as text rather than as numbers. Use a numeric column type, or convert the text to a numeric type before applying MAX().


SQL Math References AVG() MIN()


Subscribe to our YouTube Channel here



plus2net.com
alper

05-06-2009

very productive examples. it teaching GROUP BY statement by one example. thank you for your post.
David Koh

15-06-2009

Another way to get the whole row where max_mark is the highest. Instead of the below from the example: SELECT * FROM `student` WHERE mark=(select max(mark) from student) We can do: SELECT * FROM `student` ORDER BY max_mark DESC LIMIT 1 This might save db processing power instead of having 2 select statements
smo

17-06-2009

This is explained here in getting highest number by using limit
rammohan

26-06-2009

how to get the last entry in pages in a table
ajay

30-07-2009

how to get name of topper of every class
super

10-08-2009

What if you had two or three top students (say arnold got 85 as well), how would you display the name of all of them with there mark?
smo

11-08-2009

You can display top 3 by using order by and limit command. Here is the sql to display top three records.
arcavalierenero

12-09-2009

This sample isn't correct: SELECT id,name,class,MAX(mark) as max_mark FROM `student`
smo

12-09-2009

Yes, you are right. To display matching records we have to use subquery. The content is modified with the above explanation.
Doug M

15-09-2009

I got a complex array I need to build from SQL. Using a theory like this, how could I retrieve the top 3 scores per game from a highscores table? Got a mod I am working on where people are asking that. I am hoping there is a simple SQL solution rather than building a complex array.
smo

17-09-2009

you can use limit and order by to get top 3 records.
karthi

06-01-2010

how to display first 2 toppers in the class? any idea..
piyush

15-04-2010

I wanted to know how to find the max salary between two table pl tell me
rakesh7434

07-05-2010

i have a table with some data i need to reproduce with same data and add new cols to it how to do it please tell me
Babs

18-05-2010

how do i pick the data with the highest currency from dis data? name itemdesc tamt smith longe 450 smith longe 470
sai

01-07-2010

how to return a zero value if selected value of max(columnname) doesnot exist.
manmohan

29-07-2010

How to get result like this id name class mark 1 John Deo Four 75 2 Max Ruin Three 85 display max marks in each class with its other associated fields
dbl

03-08-2010

@manmohan something along the lines of select * from table group by class order by mark asc should do what you want
Atef

03-10-2010

how do i select the max ID value from table and insert this value in other ID record which in other table
anji

04-10-2010

I need max value ( in emp_city)in the below talbe emp_name Emp_id Emp_city abc 12 cc01 bbc 13 cc02 abc 12 cc01 agc 15 cc03 dbc 16 cc01 Result cc01 How can i get this one?please tell me anyone?
DARSHAN BHAWSAR

08-11-2010

I need an SQL to get the last updated transaction on the basis of date. eg. Date Remarks 13/09/10 a 13/10/10 b SQL should return value as b since it is last updated transaction.
satish.s

02-05-2011

Dear Sir/madam, We r dong project on vb with oledb conn with msaccess 2003 how to fetch maximum value of msaccess field to vb 6.0 please send us select statement of this query please do needfull Regards Satish.S
zorrs

20-05-2011

how to select the row/field base on the latest date
sadia

02-06-2011

i want to find sum of maximum marks of a student.e.g student got subject A = gpa 2.5 subject B= gpa 3 subject A= gpa 2 (reappeared) subjct A= gpa 3.5 (reappeared) sum of gpa= 3+3.5 what would be the query for it?
sanzoO

07-10-2011

There is table say tbl_data which have the folling data id, user_name, mark1, mark2, mark3, mark4 ...... what ll be the query for finding the name of 3rd heighest scrorer Help me out...
some12die4

17-02-2012

Anoher simple way is just to use order and limit like this: SELECT xx,xx2 FROM students ORDER BY mark DESC LIMIT 1
Bim

17-02-2012

@sanzoO select * from `tbl_data` ORDER BY
`mark1`+`mark2`+`mark3`+`mark4`
DESC LIMIT 2,1;
@zorrs & @DARSHAN BHAWSAR
have to be more specific, group by `id`
ORDER BY max(`latestdate`) DESC ? @anji
SELECT * FROM `table` ORDER BY `Emp_id`
DESC LIMIT 1;
vinoth

12-09-2012

i have tried to be in inner join Based,Find Max Value
The Query Is:
select Last(b.ProgramName),RDate,ValidDate,
OfferOpenDate,Last(c.OfferID) from
tblStudentReg as a left outer join
(tblOfferProgram as b left outer
join tblOfferScheme as c on
b.OfferID=c.OfferID)on a.ProgramName=b.ProgramName where
RegistrationNO=1 group by
RDate,ValidDate,OfferOpenDate
arlene ballada

08-11-2012

how to get the largest average balance in Sql....can you help?
vishakha gupta

16-04-2014

Hi, i wanna know that on selecting any value in my form then retreving the data only some value from my table within my database on the basis of matching the starting string i.e. "CA-1" in php then how can i do this?
please ans.
Sirjiskit

06-05-2014

How will I find the position of students in examination from the average
Vijay Sharma

07-07-2014

hello,tell me that how i fine the second largest salary in a emp table.
vijay

23-08-2014

i have a table that table name is student
how i get max(mark) in max(Id) and min(mark) in min(Id) in singl tbl?
rakesh chand

30-01-2015

very very Thank you for this tutorial.
prameela

16-03-2015

we have a two tables mid1,mid2, by using that we sholud get the best of the two.
Ujjwal Kumar

09-11-2015

I am trying the fetch the biggest value from any where in database table sql query but I am unable to do so please if anybody know please share query???
L.Sankaranarayanan

14-11-2015

SELECT id,name,class,MAX(mark) as max_mark FROM `student` didn't work in my h2 An error message showing 'group by ' necessary after stuent
Deepak

06-06-2016

level_type = 1;
i want to get all maximum maximum value where level_type='1';
like a example
user1=50;
user2 = 80;
user3 = 100;
user4=10;
then result should be = 100,80,50,10.. thanks in advance ...sorry for weak english

smo1234

20-06-2016

For this you need Order by Query
jyoti

13-07-2016

I am trying the fetch the biggest value from any where in database table sql query but I am unable to do so please if anybody know please share query?.......
khenu

08-04-2017

i am trying to get the maximum value for this list of numbers 0,1,2,3,4,5,10,12,13,14,15 using SELECT MAX(column-name)
table-name would give a result of 5 and not 15. Why?
smo1234

10-04-2017

It is considering the data as chars and first character is used for ranking, Now the highest first char is 5 , so it is returning 5 as maximum value. You need to convert the data to integer first and then apply MAX query. This part is added now. If all your data is integer then you can change the column type to Integer and they try MAX command
yagnesh patel

23-11-2018

I want to result in mysql query as given
max times stored value in table

e.g.
id name
1 a
2 b
3 c
4 a
5 a

so it should come "a"
smo1234

25-11-2018

You can use ORDER BY with LIMIT query.
Edward

19-04-2019

Very useful article....its has explained very clearly why data was not returning properly from my query as one of the number fields in my database column was formatted a VARCHAR,therefore trying to return a max() on this field was returning the wrong figure. The explanation offered is brilliant ! Thank you
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
©2000-2026   plus2net.com   All rights reserved worldwide Privacy Policy Disclaimer