284

I am trying to find a MySQL query that will find DISTINCT values in a particular field, count the number of occurrences of that value and then order the results by the count.

example db

id         name
-----      ------
1          Mark
2          Mike
3          Paul
4          Mike
5          Mike
6          John
7          Mark

expected result

name       count
-----      -----
Mike       3
Mark       2
Paul       1
John       1
Dharman
  • 30,962
  • 25
  • 85
  • 135
JimmyJ
  • 4,311
  • 3
  • 27
  • 25

4 Answers4

496
SELECT name,COUNT(*) as count 
FROM tablename 
GROUP BY name 
ORDER BY count DESC;
Gruber
  • 2,196
  • 5
  • 28
  • 50
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 2
    What exactly is the group by doing here? It is not clear what is purpose is? It seems it should work with out it if you where just reading it plainly. – Tegra Detra Sep 19 '11 at 15:46
  • 22
    While Amber's query is the correct answer for the question, I would like to make a correction on her comment to avoid leading new people astray. If you leave off the "group by" in a MySQL query, you don't get [Mike, 1], [Mike, 1], you get a single result which will be the name on the FIRST row returned, and a count of number of rows in the table, so in this case [Mark, 7]. count(), as an aggregate function works on the entire dataset, suming, counting, or concating the specified field down to one row. Group by subdivides the dataset into chunks based on unique combos of the specified fields – Avatar_Squadron Aug 24 '12 at 16:37
  • @Avatar_Squadron Quite right; I've removed the previous comment - it was off the top of my head, and I don't tend to actually observe the results of count without group by much. :) – Amber Aug 25 '12 at 02:59
  • 3
    Something I struggled with was eliminating results with no duplicates. You can't throw a `count(*) > 1` into a `where` clause because it's an aggregate functions. You also get a very unhelpful message: "Invalid use of group function." The right way is to alias the count `name,COUNT(*) as cnt` and add a [having clause](http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html) like so: `HAVING count > 1`. – Patrick M May 14 '13 at 00:25
  • 4
    @PatrickM Yes, `HAVING` is for conditions that should be applied after aggregation, whereas `WHERE` is for conditions that should be applied before it. (Another way of thinking of this is that `WHERE` applies to the original row data; `HAVING` applies to the output row data.) – Amber May 17 '13 at 23:22
  • @Amber please improve this code-only answer -- it is the dupe target for many pages. – mickmackusa Apr 20 '21 at 09:56
  • @mickmackusa code-only doesn't necessarily mean bad, especially when the code is both straightforward and relatively self-describing. Adding more words simply to make something not code-only is wasteful. – Amber Apr 20 '21 at 13:27
  • I am sorry to hear that this is your stance. High rep users that earn big rep from code-only answers are role modeling to new users that code-only answers are absolutely fine. New contributors can't always differentiate straightforward/self-describing code from otherwise. If you don't want to explain it, say something else -- add links, add a demo link, explain the difference between `COUNT(1)` & `COUNT(*)`, or even links to documentation, etc. There are many ways to avoid a code-only answer which are generous without being noisy. – mickmackusa Apr 20 '21 at 21:05
  • @Avatar_Squadron you may like to add your very relevant point to the answer via an edit. This feels like a consideration that researchers would benefit from, but not everyone bothers to read comments. – mickmackusa Apr 21 '21 at 04:48
  • This query gives an error: `In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column ***; this is incompatible with sql_mode=only_full_group_by` – The answer should be improved regarding this issue. For example: https://dba.stackexchange.com/a/290104/200937 – Avatar Jan 05 '22 at 06:27
  • @Avatar this query *does* contain a GROUP BY, so if you're getting that error, you're running something that is not this query. – Amber Jan 05 '22 at 14:06
21

What about something like this:

SELECT
  name,
  count(*) AS num
FROM
  your_table
GROUP BY
  name
ORDER BY
  count(*)
  DESC

You are selecting the name and the number of times it appears, but grouping by name so each name is selected only once.

Finally, you order by the number of times in DESCending order, to have the most frequently appearing users come first.

Neithan Max
  • 11,004
  • 5
  • 40
  • 58
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • Your query helped me. It returns a few rows as a result. I also wanted to know how to find the count of this result. Tried a few queries but it doesn't seem to be able to do a count on an aggregate. Could you help with that? – Nav Jun 02 '16 at 05:41
  • @Nav - a count of what? The number of rows returned? That's `SELECT COUNT(DISTINCT name) as count FROM your_table` For a count of the total rows of the table, do Pascal's query without the `group by` statement. – Autumn Leonard Dec 08 '16 at 21:15
  • @AutumnLeonard thanx man. I got the answer from your comment then the answer.. :) – Leo the lion Sep 23 '21 at 05:21
9

Just changed Amber's COUNT(*) to COUNT(1) for the better performance.

SELECT name, COUNT(1) as count 
FROM tablename 
GROUP BY name 
ORDER BY count DESC;
aerin
  • 20,607
  • 28
  • 102
  • 140
  • 1
    Actually what you said is partial [here](https://stackoverflow.com/a/5180023/10342514) – James Nov 10 '19 at 10:51
0
$sql ="SELECT DISTINCT column_name FROM table_NAME";

$res = mysqli_query($connection_variable,$sql);

while($row = mysqli_fetch_assoc($res))
{
$sqlgetnum = "select count(*) as count from table_NAME where column_name= '$row[column_name]'";
}

WORKED PROPERLY FOR ME

GROUP BY DOES GIVE ALL DISTINCT VALUES

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103