Как найти max от count

While using … HAVING COUNT(*) = ( …MAX().. ) works:

  • Within the query, it needs almost the same sub-query twice.
  • For most databases, it needs a 2nd level sub-query as MAX( COUNT(*) )
    is not supported.

While using TOP / LIMIT / RANK etc works:

  • It uses SQL extensions for a specific database.

Also, using TOP / LIMIT of 1 will only give one row – what if there are two or more doctors with the same maximum number of patients?

I would break the problem into steps:

Get target field(s) and associated count

SELECT docName, COUNT( patient ) AS countX
FROM doctor
GROUP BY docName

Using the above as a ‘statement scoped view’, use this to get the max count row(s)

WITH x AS
(
    SELECT docName, COUNT( patient ) AS countX
    FROM doctor
    GROUP BY docName
)
SELECT x.docName, x.countX
FROM x
WHERE x.countX = ( SELECT MAX( countX ) FROM x )

The WITH clause, which defines a ‘statement scoped view’, effectively gives named sub-queries that can be re-used within the same query.

While this solution, using statement scoped views, is longer, it is:

  • Easier to test
  • Self documenting
  • Extendable

It is easier to test as parts of the query can be run standalone.

It is self documenting as the query directly reflects the requirement
ie the statement scoped view lists the target field(s) and associated count.

It is extendable as if other conditions or fields are required, this can be easily added to the statement scoped view.
eg in this case, the table stucture should be changed to include a doctor-id as a primary key field and this should be part of the results.

Last update on August 19 2022 21:51:36 (UTC/GMT +8 hours)

MAX() with Count function

In this part, you will see the usage of SQL COUNT() along with the SQL MAX().

Example:

To get the maximum number of agents as column alias ‘mycount’ from the ‘orders’ table with the following condition –

1. ‘agent_code’ should be in a group,

the following SQL statement can be used :

SELECT MAX (mycount) 
FROM (SELECT agent_code,COUNT(agent_code) mycount 
FROM orders 
GROUP BY agent_code);

Sample table: orders

Output:

MAX(MYCOUNT)
------------
           7

Pictorial Presentation :

SQL MAX() function with COUNT example

SQL MAX() and COUNT() with HAVING

To get data of ‘agent_code’, and number of agents for each group of ‘agent_code’ from the orders table with the following conditions –

‘agent_code’ for a group will be equal to the result of an outer query [SELECT MAX(agent_code)…….] with following condition –

the outer query produce the maximum number of agents mentioned as
‘mycount’ from an inner query [SELECT agent_code,
COUNT(agent_code) mycount FROM orders GROUP BY agent_code]
with following condition –

the inner query produced the data ‘agent_code’ number of agents as
column alias ‘mycount’ from the ‘orders’ table with the following
condition –

‘agent_code’ should be in a group,

the following SQL statement can be used :

SELECT agent_code, COUNT(agent_code) 
FROM orders  GROUP BY agent_code 
HAVING COUNT (agent_code)=( 
SELECT MAX(mycount) 
FROM ( 
SELECT agent_code, COUNT(agent_code) mycount 
FROM orders 
GROUP BY agent_code));

Sample table: orders

Output:

AGENT_CODE COUNT(AGENT_CODE)
---------- -----------------
A002                       7

SQL MAX() function with COUNT WITH HAVING example

Note: Outputs of the said SQL statement shown here is taken by using Oracle Database 10g Express Edition

Here is a slide presentation of all aggregate functions.

Check out our 1000+ SQL Exercises with solution and explanation to improve your skills.

Previous: Max Date
Next: Min function

SQL: Tips of the Day

Get top 1 row of each group:

;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC) AS rn
   FROM DocumentStatusLogs
)
SELECT *
FROM cte
WHERE rn = 1

Ref: https://bit.ly/390IEAj

We are closing our Disqus commenting system for some maintenanace issues. You may write to us at reach[at]yahoo[dot]com or visit us
at Facebook

This question is old, but was referenced in a new question on dba.SE. I feel the best solutions haven’t been provided. Plus, there are new, faster options.

Question in the title

Can I do a max(count(*)) in SQL?

Yes, you can achieve that by nesting an aggregate function in a window function:

SELECT m.yr
     , count(*) AS movie_count
     , max(count(*)) OVER () AS max_ct
FROM   casting c
JOIN   movie   m ON c.movieid = m.id
WHERE  c.actorid = (SELECT id FROM actor WHERE name = 'John Travolta')
GROUP  BY m.yr
ORDER  BY count(*) DESC;

db<>fiddle here

That’s standard SQL. Postgres introduced it with version 8.4 (released 2009-07-01, before this question was asked. Other RDBMS should be capable of the same.
Consider the sequence of events in a SELECT query:

  • Best way to get result count before LIMIT was applied

Possible downside: window functions do not aggregate rows. You get all rows left after the aggregate step. Useful in some queries, but not ideal for this one.

To get one row with the highest count, you can use ORDER BY ct DESC FETCH FIRST 1 ROW ONLY:

SELECT c.yr, count(*) AS ct
FROM   actor   a
JOIN   casting c ON c.actorid = a.id
WHERE  a.name = 'John Travolta'
GROUP  BY c.yr
ORDER  BY ct DESC
FETCH  FIRST 1 ROW ONLY;

Using only basic SQL features, available in any halfway decent RDBMS. Most popular RDBMS (also) support alternative syntax for FETCH FIRST with LIMIT, TOP or ROWNUM. See:

  • SQL select elements where sum of field is less than N

Or you can get one row per group with the highest count with DISTINCT ON (only Postgres):

  • Select first row in each GROUP BY group?

Actual Question

I need to get the rows for which count(*) is max.

There may be more than one row with the highest count.

SQL Server has had the feature WITH TIES for some time – with non-standard syntax:

SELECT TOP 1 WITH TIES
       m.yr, count(*) AS movie_count
FROM   casting c
JOIN   movie   m ON c.movieid = m.id
WHERE  c.actorid = (SELECT id FROM actor WHERE name = 'John Travolta')
GROUP  BY m.yr
ORDER  BY count(*) DESC;  -- can't sort by year for this

db<>fiddle here

PostgreSQL 13 added WITH TIES with standard SQL syntax:

SELECT m.yr, count(*) AS movie_count
FROM   casting c
JOIN   movie   m ON c.movieid = m.id
WHERE  c.actorid = (SELECT id FROM actor WHERE name = 'John Travolta')
GROUP  BY m.yr
ORDER  BY count(*) DESC  -- can't sort by year for this
FETCH  FIRST 1 ROWS WITH TIES;

db<>fiddle here

This should be the fastest possible query. Further reading:

  • Get top row(s) with highest value, with ties

  • PostgreSQL equivalent for TOP n WITH TIES: LIMIT “with ties”?

To sort results by additional criteria (or for older versions of Postgres or other RDBMS without WITH TIES), use the window function rank() in a subquery:

SELECT yr, movie_count
FROM  (
   SELECT m.yr, count(*) AS movie_count
        , rank() OVER (ORDER BY count(*) DESC) AS rnk
   FROM   casting c
   JOIN   movie   m ON c.movieid = m.id
   WHERE  c.actorid = (SELECT id FROM actor WHERE name = 'John Travolta')
   GROUP  BY m.yr
   ) sub
WHERE  rnk = 1
ORDER  BY yr;  -- optionally sort by year

All major RDBMS support window functions nowadays.

Здесь мой код:

    select yr,count(*)  from movie
join casting on casting.movieid=movie.id
join actor on casting.actorid = actor.id
where actor.name = 'John Travolta'
group by yr

Здесь вопрос

Какими были самые долгие годы для “Джона Траволты”. Покажите количество фильмов, которые он сделал за каждый год.

Здесь структура таблицы:

movie(id, title, yr, score, votes, director)
actor(id, name)
casting(movieid, actorid, ord)

Это результат, который я получаю:

yr  count(*)
1976    1
1977    1
1978    1
1981    1
1994    1
etcetc

Мне нужно получить строки, для которых count(*) max.

Как это сделать?

4b9b3361

Ответ 1

Использование:

  SELECT m.yr, 
         COUNT(*) AS num_movies
    FROM MOVIE m
    JOIN CASTING c ON c.movieid = m.id
    JOIN ACTOR a ON a.id = c.actorid
                AND a.name = 'John Travolta'
GROUP BY m.yr
ORDER BY num_movies DESC, m.yr DESC

Заказ num_movies DESC будет содержать самые высокие значения в верхней части набора результатов. Если многолетний период имеет одинаковый счет, m.yr поместит последний год вверху… до следующего значения num_movies.


Нет, вы не можете группировать агрегированные функции друг над другом в том же предложении SELECT. Внутренний агрегат должен выполняться в подзапросе. IE:

SELECT MAX(y.num)
  FROM (SELECT COUNT(*) AS num
          FROM TABLE x) y

Ответ 2

Просто закажите count(*) desc, и вы получите наивысший результат (если вы объедините его с limit 1)

Ответ 3

SELECT * from 
(
SELECT yr as YEAR, COUNT(title) as TCOUNT
FROM actor
JOIN casting ON actor.id = casting.actorid
JOIN movie ON casting.movieid = movie.id
WHERE name = 'John Travolta'
GROUP BY yr
order by TCOUNT desc
) res
where rownum < 2

Ответ 4

с этого сайта – http://sqlzoo.net/3.htm
2 возможных решения:

с TOP 1 a ORDER BY… DESC:

SELECT yr, COUNT(title) 
FROM actor 
JOIN casting ON actor.id=actorid
JOIN movie ON movie.id=movieid
WHERE name = 'John Travolta'
GROUP BY yr
HAVING count(title)=(SELECT TOP 1 COUNT(title) 
FROM casting 
JOIN movie ON movieid=movie.id 
JOIN actor ON actor.id=actorid
WHERE name='John Travolta'
GROUP BY yr
ORDER BY count(title) desc)

с MAX:

SELECT yr, COUNT(title) 
FROM actor  
JOIN casting ON actor.id=actorid    
JOIN movie ON movie.id=movieid
WHERE name = 'John Travolta'
GROUP BY yr
HAVING 
    count(title)=
        (SELECT MAX(A.CNT) 
            FROM (SELECT COUNT(title) AS CNT FROM actor 
                JOIN casting ON actor.id=actorid
                JOIN movie ON movie.id=movieid
                    WHERE name = 'John Travolta'
                    GROUP BY (yr)) AS A)

Ответ 5

Использование max с лимитом даст вам только первую строку, но если есть две или более строк с одинаковым количеством максимальных фильмов, вы можете пропустить некоторые данные. Ниже приведен способ сделать это, если у вас есть функция rank().

SELECT
    total_final.yr,
    total_final.num_movies
    FROM
    ( SELECT 
        total.yr, 
        total.num_movies, 
        RANK() OVER (ORDER BY num_movies desc) rnk
        FROM (
               SELECT 
                      m.yr, 
                      COUNT(*) AS num_movies
               FROM MOVIE m
               JOIN CASTING c ON c.movieid = m.id
               JOIN ACTOR a ON a.id = c.actorid
               WHERE a.name = 'John Travolta'
               GROUP BY m.yr
             ) AS total
    ) AS total_final 
   WHERE rnk = 1

Ответ 6

Следующий код дает вам ответ. Он по существу реализует MAX (COUNT (*)), используя ALL. Преимущество состоит в том, что он использует очень простые команды и операции.

SELECT yr, COUNT(title)
FROM actor
JOIN casting ON actor.id = casting.actorid
JOIN movie ON casting.movieid = movie.id
WHERE name = 'John Travolta'
GROUP BY yr HAVING COUNT(title) >= ALL
  (SELECT COUNT(title)
   FROM actor
   JOIN casting ON actor.id = casting.actorid
   JOIN movie ON casting.movieid = movie.id
   WHERE name = 'John Travolta'
   GROUP BY yr)

Ответ 7

В зависимости от используемой базы данных…

select yr, count(*) num from ...
order by num desc

Большая часть моего опыта в Sybase, который использует какой-то другой синтаксис, чем другие БД. Но в этом случае вы назовете свой столбец count, чтобы вы могли сортировать его по убыванию. Вы можете сделать еще один шаг и ограничить результаты до первых 10 строк (чтобы найти его 10 самых загруженных лет).

Ответ 8

     select top 1 yr,count(*)  from movie
join casting on casting.movieid=movie.id
join actor on casting.actorid = actor.id
where actor.name = 'John Travolta'
group by yr order by 2 desc

Ответ 9

Этот вопрос старый, но был указан в новом вопросе на dba.SE. Я чувствую, что лучшие решения не были предоставлены, но я добавляю еще один.

Прежде всего, при условии ссылочной целостности (как правило, с ограничениями внешних ключей), вам не нужно вообще присоединяться к таблице movie. Этот мертвый груз в вашем запросе. Все ответы пока не указывают на это.


Можно ли сделать max(count(*)) в SQL?

Чтобы ответить на вопрос в заголовке: Да, в Postgres 8.4 (выпущен 2009-07-01, перед тем, как этот вопрос был задан) или позже, вы можете добиться этого, вложив агрегированную функцию в функция окна:

SELECT c.yr, count(*) AS ct, max(count(*)) OVER () AS max_ct
FROM   actor   a
JOIN   casting c ON c.actorid = a.id
WHERE  a.name = 'John Travolta'
GROUP  BY c.yr;

Рассмотрим последовательность событий в запросе SELECT:

  • Лучший способ получить результат до применения LIMIT

(возможный) недостаток: функции окна не группируют строки. Вы получаете все строки, оставшиеся после совокупного шага. Полезно в некоторых запросах, но не идеально для этого.


Чтобы получить одну строку с наивысшим счетчиком, вы можете использовать ORDER BY ct LIMIT 1 как @wolph hinted:

SELECT c.yr, count(*) AS ct
FROM   actor   a
JOIN   casting c ON c.actorid = a.id
WHERE  a.name = 'John Travolta'
GROUP  BY c.yr
ORDER  BY ct DESC
LIMIT  1;

Использование только базовых функций SQL, доступных в любой половине допустимой РСУБД – реализация LIMIT различается:

  • Элементы выбора SQL, где сумма поля меньше N

Или вы можете получить одну строку на группу с наивысшим счетчиком с помощью DISTINCT ON (только Postgres):

  • Выберите первую строку в каждой группе GROUP BY?

Ответ

Но вы просили:

… строки, для которых count (*) max.

Возможно, более одного. Наиболее элегантным решением является функция окна rank() в подзапросе. Ryan предоставил запрос, но это может быть проще (подробности в моем ответе выше):

SELECT yr, ct
FROM  (
   SELECT c.yr, count(*) AS ct, rank() OVER (ORDER BY count(*) DESC) AS rnk
   FROM   actor   a
   JOIN   casting c ON c.actorid = a.id
   WHERE  a.name = 'John Travolta'
   GROUP  BY c.yr
   ) sub
WHERE  rnk = 1;

В настоящее время все основные функции поддержки RDBMS поддерживаются. За исключением MySQL и forks (MariaDB, похоже, их реализовала наконец в версии 10.2).

Ответ 10

Благодаря последнему ответу

SELECT yr, COUNT(title)
FROM actor
JOIN casting ON actor.id = casting.actorid
JOIN movie ON casting.movieid = movie.id
WHERE name = 'John Travolta'
GROUP BY yr HAVING COUNT(title) >= ALL
  (SELECT COUNT(title)
   FROM actor
   JOIN casting ON actor.id = casting.actorid
   JOIN movie ON casting.movieid = movie.id
   WHERE name = 'John Travolta'
   GROUP BY yr)

У меня была такая же проблема, мне нужно было знать только те записи, которые их счетчик соответствует максимальному счету. (это может быть одна или несколько записей)

Мне нужно узнать больше о “ALL clause”, и это именно то простое решение, которое я искал.

Ответ 11

create view sal as
select yr,count(*) as ct from
(select title,yr from movie m, actor a, casting c
where a.name='JOHN'
and a.id=c.actorid
and c.movieid=m.id)group by yr

—– СМОТРЕТЬ СМОТРЕТЬ —–

select yr from sal
where ct =(select max(ct) from sal)

Ю.Р.
2013

4aineg

0 / 0 / 0

Регистрация: 07.08.2008

Сообщений: 23

1

18.11.2008, 20:16. Показов 21746. Ответов 2

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

подскажите пожалуйста как найти самый покупаемый товар
где нужно будет посчитать повторяющиеся номера Goods_num и выбрать максимальное количество

T-SQL
1
2
3
select max(Goods_num) from ContGoods
         where max(Goods_num) in
               (select count(Goods_num) from ContGoods)
Contract1_num Goods_num
————– ———–
1 1
2 2
3 2
3 3
4 4
5 5

сама таблица ContGoods



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

18.11.2008, 20:16

Ответы с готовыми решениями:

Выбрать MAX из COUNT
Требуется выбрать сотрудника, который заключил максимальное количество договоров.

SELECT…

Запрос max(count() с группировкой по годам
Добрый вечер!

Есть таблица res, в ней 3 столбца birth_date, res_name, sex.
Подскажите, возможно…

Задача для курсовой: определить значение z=max(a, 2b)*max(2a-b,b), где max(x, y)-максимальные из чисел х и у
Определить значение z=max(a, 2b)*max(2a-b,b), где max(x, y)-максимальные из чисел х и у. Задачу…

Найти max значение в каждой группе чисел и max из полученных max
Заданы три группы чисел

10, 20, 50
100, 200, 75
A, B, C

Найти max значение в каждой группе…

2

Green

1922 / 427 / 41

Регистрация: 12.07.2007

Сообщений: 2,062

19.11.2008, 03:23

2

за достоверность не ручаюсь, но возможно так

T-SQL
1
select max(goods_count) from (select count(Goods_num) as goods_count from ContGoods) as tbl



0



artyuri

26.11.2008, 20:13

3

запрос:

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
select goods_num, cf_num1
from (  select goods_num,count(*) as cf_num1
    from contgoods_tmp
    group by goods_num
      ) t1
where t1.cf_num1 = 
    (   select max(cf_num)
        from (
            select goods_num,count(*) as cf_num
            from contgoods_tmp
            group by goods_num
              ) t2 
    )

работает на sql server2000

пример:

T-SQL
1
select * from contgoods_tmp
id goods_num
1 1
2 2
3 3
4 5
5 4
6 2
7 3
8 4
9 6
10 2

результат:

goods_num cf_num1
2 3

Добавлено через 54 минуты 5 секунд
вариант немного короче предыдущего:

T-SQL
1
2
3
4
5
6
7
8
9
select goods_num,count(*) as cf_num
from contgoods_tmp
group by goods_num
having count(*) = (select max(cf_num)
           from (
            select goods_num,count(*) as cf_num
            from contgoods_tmp
            group by goods_num
              ) t1 )

(проверено – работает)

IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

26.11.2008, 20:13

Помогаю со студенческими работами здесь

Sql MAX( COUNT)
Можно ли составить такой запрос.

НУжно вытащить Имя города, Колличество Квартир, Цена за…

Запрос MAX(COUNT(*)
Было получено задание, по работе с системным каталогом: выбрать пользователя имеющее максимальное…

Запрос max из count
Здравствуйте.
Столкнулся с такой задачей. Есть БД содержащая инфу о грузоперевозках по…

Определить значение Z=max(a,2b)*max(2a-b,b), где max(x,y)-максимальное из чисел x,y
Помогите решить задачу:
Определить значение Z=max(a,2b)*max(2a-b,b), где max(x,y)-максимальное из…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

3

Добавить комментарий